Sécurité appliquée · L3 · Section 4/5
Chiffrement AES
Progression
#Chiffrement AES (Advanced Encryption Standard)
AES est une primitive de chiffrement par blocs: elle transforme 128 bits en 128 bits sous l'action d'une clé de 128, 192 ou 256 bits. En soi, elle ne chiffre qu'un bloc. Tout le reste (traiter des messages longs, garantir l'authenticité, générer les nonces) relève du mode d'opération et du schéma, jamais de la primitive. Comprendre cette frontière est l'objet de cette page.
Prérequis
- Représentations binaire et hexadécimale, opération XOR.
- Section « Cryptographie de base » du même module (primitives vs schémas).
- Arithmétique dans GF(2^8) pour les curieux (MixColumns); le reste se lit sans elle.
Objectifs d'apprentissage
- Décrire l'état AES (matrice 4x4 octets) et le rôle de chaque transformation d'un tour: SubBytes, ShiftRows, MixColumns, AddRoundKey.
- Expliquer pourquoi AES seul ne suffit pas: bloc de taille fixe, et besoin d'un mode d'opération.
- Choisir un mode approprié (GCM plutôt qu'ECB) et reconnaître les usages dangereux.
#Principe
L'AES est un chiffrement par blocs à clé secrète, standardisé par le NIST en 2001 après un concours public (compétition remportée par Rijndael). Il traite des données par blocs de 128 bits, avec des clés de 128, 192 ou 256 bits (AES-128, AES-192, AES-256), qui déterminent le nombre de tours: 10, 12 ou 14.
#Animation interactive
Le visualiseur suivant déroule les transformations sur un état réel: observez l'effet de chaque étape sur la matrice 4x4.
#Structure de l'AES
#Organisation des données
- Taille de bloc: 128 bits (16 octets), quelle que soit la longueur de clé.
- État: les 16 octets sont rangés en matrice 4x4, remplie colonne par colonne.
- Clé: 128, 192 ou 256 bits; le key schedule en dérive 11, 13 ou 15 clés de tour de 128 bits.
#Tours
Chaque tour applique quatre transformations:
- SubBytes: substitution octet par octet via la S-box (inverse dans GF(2^8) suivi d'une transformation affine). Apporte la non-linéarité, seule protection contre la cryptanalyse linéaire et différentielle.
- ShiftRows: rotation des lignes 1, 2, 3 de 1, 2, 3 octets vers la gauche. Diffuse les octets entre les colonnes.
- MixColumns: multiplication de chaque colonne par une matrice fixe dans GF(2^8). Assure la diffusion: un octet du clair influence les 4 octets de sa colonne (omise au dernier tour).
- AddRoundKey: XOR de l'état avec la clé de tour. Seule opération qui fait intervenir la clé; les trois autres sont publiques et identiques pour toutes les clés.
Le tour initial se limite à un AddRoundKey, et le dernier omet MixColumns (afin que le déchiffrement reste symétrique). Pourquoi cet entrelacement ? SubBytes seul resterait local à chaque octet; ShiftRows et MixColumns propagent chaque octet vers tout l'état en deux tours; le XOR avec la clé dilue le tout. Au bout de 10 tours, chaque bit du chiffré dépend de chaque bit du clair et de chaque bit de la clé.
#Key schedule
Les clés de tour se dérivent de la clé maître par rotations (RotWord), substitutions (SubWord) et constantes de tour (Rcon), de sorte que deux clés voisines ne soient pas liées simplement. Le key schedule ne renforce pas une clé faible: une clé issue d'un mot de passe reste attaquable par dictionnaire quel que soit le nombre de tours.
#Manipuler les transformations (Python)
Observons chaque transformation avec la S-box réelle de l'AES (tronquée ici pour rester lisible; la table complète compte 256 octets).
1# Extrait de la S-box officielle de l'AES (premiers octets)2SBOX = [3 0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,4 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,5 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,6 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,7]8 9def sub_bytes(etat):10 """SubBytes: substitution octet par octet (SBOX tronquee ici a 64 valeurs)."""11 return [[SBOX[etat[r][c] % 64] for c in range(4)] for r in range(4)]12 13def shift_rows(etat):14 """ShiftRows: la ligne r est rotatee de r positions vers la gauche."""Points d'observation: SubBytes remplace chaque octet de façon non linéaire (les octets identiques restent identiques: la S-box est une fonction déterministe, pas un aléa); ShiftRows déplace les octets entre colonnes; AddRoundKey est le seul endroit où la clé agit. Appliquer ces transformations isolément n'est pas chiffrer: il manque les tours complets et le key schedule, sans quoi n'importe qui sait inverser.
#Utiliser AES pour de vrai: bien choisir le mode
Une application ne manipule presque jamais « AES brut »: elle utilise AES dans un mode d'opération, via une bibliothèque. Le choix du mode décide de la sécurité bien plus que la longueur de clé.
| Mode | Idée | Faiblesse principale | Usage recommandé |
|---|---|---|---|
| ECB | Chaque bloc chiffré indépendamment | Les motifs du clair transparaissent (blocs identiques, chiffres identiques) | Aucun, sauf chiffrement d'un bloc unique aléatoire (ex: clé de session) |
| CBC | Chaque bloc XOR avec le chiffré précédent, IV aléatoire | Pas d'authenticité; sensible aux padding oracles si mal composé | Legacy, avec HMAC en complément (Encrypt-then-MAC) |
| CTR | Chiffre un compteur, XOR avec le clair | Nonce réutilisé: XOR des clairs dévoilé | Avec un MAC, ou via GCM |
| GCM | CTR + MAC intégré (GHASH) | Nonce réutilisé: compromis catastrophique (clé d'authentification divulguée) | Défaut moderne: confidentialité + authenticité (AEAD) |
Résultat attendu: ECB donne 1 bloc distinct sur 4, CBC en donne 4. Transposé sur une vraie image, le mode ECB produit une version bruitée mais reconnaissable de l'original. C'est l'illustration classique du pourquoi ECB est interdit pour toute donnée structurée.
#Pièges concrets à retenir
- Nonce/IV réutilisé (GCM, CTR): avec la même clé, deux messages partiellement connus révèlent leurs différences. Un compteur strictement croissant ou un aléa correctement borné évite cela; l'essentiel est de ne jamais répéter un nonce sous une même clé.
- Clé dérivée d'un mot de passe par un simple hash: attaquable par dictionnaire sur GPU. Utiliser Argon2id, scrypt ou PBKDF2 avec itérations élevées.
- Chiffrement sans authenticité: un chiffré modifiable en douceur (padding oracle, troncature). Préférer un mode authentifié (GCM, ChaCha20-Poly1305) sauf contrainte documentée.
- Clé stockée à côté du chiffré dans le même dépôt: la confidentialité disparaît avec le dépôt. Séparer les secrets (variables d'environnement, gestionnaire de secrets).
#Exercice corrigé: déchiffrer en inversant les tours
On construit un « mini-chiffrement » pédagogique à trois tours (SubBytes simplifiée, ShiftRows, AddRoundKey avec key schedule simplifié). Objectif: écrire le déchiffrement en inversant chaque opération dans l'ordre inverse, puis vérifier le round-trip.
#Instructions
- Écrivez
inv_shift_rows(rotation vers la droite) etinv_sub_bytes(table inverse). - Parcourez les tours en ordre inverse: AddRoundKey avec la clé de tour correspondante, puis InvShiftRows, puis InvSubBytes.
- Vérifiez:
decrypt(encrypt(m)) == mpour plusieurs messages, y compris un message uniforme.
#Correction
1SBOX = {i: (i * 7 + 3) % 256 for i in range(256)} # substitution pedagogique2INV_SBOX = {v: k for k, v in SBOX.items()}3 4def add_round_key(e, k):5 return [[e[r][c] ^ k[r][c] for c in range(4)] for r in range(4)]6 7def shift_rows(e):8 return [e[r][r:] + e[r][:r] for r in range(4)]9 10def inv_shift_rows(e):11 return [e[r][-r:] + e[r][:-r] for r in range(4)]12 13def sub_bytes(e):14 return [[SBOX[b] for b in ligne] for ligne in e]Le point délicat est l'ordre. Chiffrer applique (SubBytes, ShiftRows, AddRoundKey) par tour; déchiffrer applique (AddRoundKey, InvShiftRows, InvSubBytes) du dernier tour au premier, puis annule le AddRoundKey initial. Si le round-trip échoue, testez d'abord chaque inverse isolément: les deux dernières lignes du script font ce diagnostic.
#Applications
- Communications: TLS chiffre le transit; AES-GCM y est l'un des modes AEAD les plus répandus.
- Stockage: disques chiffrés (LUKS, BitLocker), bases de données au repos. Les contraintes diffèrent du transit: un nonce ne doit jamais être réutilisé, même après restauration d'une sauvegarde.
- VPN et Wi-Fi: IPsec, WPA3; WireGuard utilise ChaCha20-Poly1305, alternative à l'AES.
- Matériel: instructions dédiées (AES-NI) rendent l'AES très rapide sur CPU moderne, y compris sur cartes à puce.
#État de la sécurité
L'AES résiste à toutes les attaques pratiques connues. Les meilleures attaques académiques (bicliques, 2011) récupèrent une clé AES-128 plus vite que la force brute, mais avec des complexités hors de portée (de l'ordre de 2^126 opérations contre 2^128). La marge est vaste; les incidents réels impliquant l'AES viennent presque toujours du mode d'opération, du nonce ou de la gestion des clés, jamais de la primitive elle-même. La leçon: investir l'effort de sécurisation sur le schéma, pas sur le choix entre AES-128 et AES-256.