Outil de cybersécurité · cryptographie expliquée
SHA-256, AES et RSA écrits à la main, sans bibliothèque, pour voir ce qui se passe à l'intérieur : les tours de calcul, l'état d'AES après chaque étape, la génération d'une clé RSA. Chaque résultat est comparé en direct à celui du module de chiffrement du navigateur (Web Crypto). On voit aussi pourquoi une petite clé RSA se casse en une fraction de seconde, et combien de temps tiendrait un mot de passe face à une attaque. Implémentations pédagogiques : elles ne doivent pas servir à protéger de vraies données.
Une empreinte de 256 bits (64 caractères hexadécimaux), quelle que soit la taille du message. Impossible de revenir au message à partir de l'empreinte, et impossible en pratique de trouver deux messages qui ont la même.
On change un seul bit du message (le dernier caractère) : environ la moitié des 256 bits de l'empreinte changent.
À chaque tour, les huit registres a à h sont mélangés avec un mot W du message et une constante K (issue des racines cubiques des premiers nombres premiers). Les registres en rouge viennent d'être recalculés (a et e) ; les autres sont décalés d'un cran.
AES seul ne protège pas contre la modification : un octet changé donne un message abîmé, parfois sans erreur. En pratique on ajoute une authentification (AES-GCM ou un HMAC), non montrée ici.
L'état est une matrice de 4 × 4 octets. Chaque tour applique SubBytes (substitution par la boîte S, calculée ici à partir de l'inverse dans le corps GF(2⁸)), ShiftRows (décalage des lignes), MixColumns (mélange des colonnes) et AddRoundKey (XOR avec la clé du tour). Les octets modifiés par l'étape sont en rouge. Dix tours pour une clé de 128 bits.
On tire deux grands nombres premiers p et q (test de Miller-Rabin), puis n = p·q et φ = (p−1)(q−1). La clé publique est (n, e) avec e = 65 537 ; la clé privée d est l'inverse de e modulo φ (algorithme d'Euclide étendu). Tout repose sur un fait : connaître n ne permet pas de retrouver p et q quand n est assez grand.
Chiffrer : c = mᵉ mod n (avec la clé publique). Déchiffrer : m = cᵈ mod n. Signer : s = H(m)ᵈ mod n avec la clé privée ; tout le monde peut vérifier avec la clé publique que sᵉ = H(m). Ici sans rembourrage (« RSA manuel ») : en vrai on utilise OAEP pour chiffrer et PSS pour signer.
La méthode rho de Pollard trouve un facteur p en environ √p essais : le temps double quand la clé gagne 4 bits. Le tableau extrapole depuis la vitesse mesurée sur ce navigateur. Pour les grandes clés, il existe une méthode bien plus rapide (le crible algébrique), mais elle reste hors de portée pour 2 048 bits : c'est la taille recommandée aujourd'hui.
Estimation simple : taille de l'alphabet utilisé puissance la longueur, réduite pour les mots de passe courants, les prénoms, les suites (azerty, 1234), les répétitions et le motif « Mot + année + ! ». Vitesses : ordres de grandeur pour une carte graphique récente. Le stockage compte autant que le mot de passe.
Un simple SHA-256 du mot de passe se calcule des milliards de fois par seconde sur une carte graphique. PBKDF2 répète le calcul des milliers de fois : la connexion d'un utilisateur prend quelques millisecondes de plus, mais chaque essai de l'attaquant devient des milliers de fois plus cher. Le sel empêche de casser tous les comptes d'un coup avec des tables précalculées. Pour des données de santé, c'est le minimum attendu (avec bcrypt, scrypt ou Argon2).
Toutes les fonctions sont écrites à la main dans crypto.js : SHA-256 (FIPS 180-4), HMAC, PBKDF2 (RFC 8018), AES-128 (FIPS 197) en modes CBC et CTR, RSA avec les grands entiers du langage (BigInt), test de primalité de Miller-Rabin, Euclide étendu et rho de Pollard. Les résultats sont vérifiés en direct contre Web Crypto, le module de chiffrement du navigateur, et dans les tests contre le module crypto de Node.
Ces implémentations ne sont pas protégées contre les attaques par canaux auxiliaires (temps de calcul, cache) et le RSA est sans rembourrage : c'est un outil pour comprendre, pas pour protéger. Rien de ce qui est tapé ne quitte la page.