Le nonce, le détail qui fait tout s'effondrer
Unicité vitale, aléatoire contre compteur, borne d'anniversaire et temps constant : pourquoi le nombre le moins secret du système est aussi le plus dangereux.
Au chapitre précédent, tu as vu que l’AEAD garantit confidentialité et intégrité en une seule opération, à condition que ses paramètres soient utilisés correctement. Le nonce fait partie de ces paramètres. Et sa contrainte d’usage est absolue.
En 2016, des chercheurs ont publié la “Forbidden attack” contre AES-GCM. L’attaque ne casse pas l’algorithme. Elle exploite une seule erreur d’utilisation : réutiliser le même nonce avec la même clé. Résultat : non seulement les deux messages se retrouvent partiellement exposés, mais la clé d’authentification interne (la clé GHASH, dérivée du polynôme de hachage de GCM) peut être reconstruite par l’adversaire. Quand la clé GHASH est connue, l’intégrité s’effondre entièrement : l’adversaire peut forger des tags valides pour n’importe quel message.
À la fin de ce chapitre, tu sauras expliquer pourquoi l’unicité du nonce est une contrainte de sécurité et non une convention, montrer ce que la réutilisation révèle via l’intuition du “two-time pad”, distinguer les stratégies aléatoire et compteur pour la génération de nonces, et comprendre pourquoi la comparaison de tags doit s’effectuer en temps constant.
Le nonce
Le nonce Nonce Valeur utilisée une seule fois avec une clé donnée. C'est l'unicité qui importe, non le secret : réutiliser un nonce avec la même clé brise complètement le schéma. Un nonce aléatoire de 192 bits (XChaCha20) offre une probabilité de collision négligeable, tandis qu'un compteur de 96 bits (AES-GCM, ChaCha20-Poly1305) exige une gestion rigoureuse pour ne jamais dépasser 2^32 messages par clé. Source : RFC 8439 (contraction de “number used once”) est une valeur transmise en clair avec chaque message chiffré. Son rôle est précis : garantir que deux chiffrements du même texte clair avec la même clé produisent des chiffrés différents.
Ce qui compte n’est pas sa confidentialité, mais son unicité. Un nonce peut être lu par n’importe qui sur le réseau sans que cela affecte la sécurité. En revanche, utiliser deux fois le même nonce avec la même clé, même pour deux messages distincts, brise des garanties fondamentales.
La taille et la stratégie de génération varient selon la primitive. AES-GCM utilise un nonce de 96 bits. XChaCha20-Poly1305 utilise un nonce de 192 bits. Ces différences ont des conséquences concrètes sur la façon dont on génère les nonces, comme on le verra plus loin.
Réutilisation : la catastrophe
L’intuition du two-time pad
Pour comprendre pourquoi la réutilisation du nonce est catastrophique, il suffit de regarder ce que fait un chiffrement à flot sous le capot.
Un chiffrement à flot (comme le flux de clé dans ChaCha20 ou le mode CTR sous AES-GCM) génère un flux pseudo-aléatoire depuis la clé et le nonce . Le texte clair est XORé avec ce flux :
Si deux messages et sont chiffrés avec le même et le même , leurs chiffrés sont :
Un adversaire qui dispose des deux chiffrés calcule :
Le flux de clé s’annule. L’adversaire obtient directement le XOR des deux textes clairs. Si l’un des deux messages est connu (ou devinable, comme un en-tête de protocole fixe), l’autre est immédiatement récupérable. C’est ce qu’on appelle le “two-time pad”, par analogie avec le one-time pad dont il rompt l’invariant fondamental.
Le composant ci-dessous illustre cette mécanique. Édite les deux messages et observe comment le XOR des chiffrés révèle directement la combinaison des textes clairs. Modifie le premier message pour qu’il ressemble à un en-tête de protocole connu, et regarde ce que le champ “récupéré” affiche pour le second.
La Forbidden attack : quand l’intégrité s’effondre aussi
La fuite des textes clairs n’est que la première conséquence. Dans AES-GCM, le tag d’authentification est calculé via une fonction polynomiale (GHASH) paramétrée par une clé interne , dérivée de la clé principale. Si deux messages chiffrés avec le même nonce et la même clé sont observés, un adversaire peut construire un système d’équations sur et le résoudre. Une fois connue, il peut forger un tag valide pour n’importe quel chiffré de son choix.
La réutilisation du nonce ne dégrade pas la sécurité d’AES-GCM : elle l’annule.
Aléatoire contre compteur
Deux stratégies principales existent pour générer des nonces uniques. Elles ont des profils de risque très différents.
Nonce aléatoire
Tirer un nonce uniformément au hasard dans un espace suffisamment grand rend les collisions négligeables. XChaCha20-Poly1305 utilise un nonce de 192 bits : il faudrait de l’ordre de messages chiffrés sous la même clé pour que la probabilité de collision atteigne seulement , un risque négligeable à toute échelle réelle. On peut générer ces nonces avec un générateur cryptographique sûr sans aucune coordination entre les parties.
AES-GCM avec son nonce de 96 bits est plus contraignant. La borne d’anniversaire nous dit que la probabilité de collision croît approximativement comme le carré du nombre de nonces générés divisé par la taille de l’espace : après messages (environ quatre milliards), la probabilité de collision avec un nonce aléatoire de 96 bits dépasse , ce qui devient préoccupant dans des systèmes à haut débit. La recommandation NIST limite l’utilisation d’une même clé AES-GCM à messages avec des nonces aléatoires.
Nonce compteur
Un compteur monotone garantit l’unicité sans limite probabiliste : chaque valeur est distincte par construction. C’est la stratégie recommandée pour AES-GCM dans des systèmes déterministes (un seul producteur, une seule clé, un état persistant).
La fragilité est opérationnelle. Un compteur doit être :
- Persistant : un redémarrage ne doit pas remettre le compteur à zéro. Si la valeur n’est pas sauvegardée en stockage durable, le nonce 0 sera réutilisé après chaque redémarrage.
- Unique par instance : dans un système distribué, deux nœuds avec la même clé qui maintiennent chacun leur propre compteur vont inévitablement produire les mêmes valeurs. Il faut soit une coordination centrale, soit inclure un identifiant unique du nœud dans le nonce.
- Non recyclable : une clé dont le compteur a atteint sa limite ne peut plus être utilisée. Il faut prévoir la rotation des clés.
La règle de conception qui en découle : une garantie qui repose sur une condition d’usage (l’unicité du nonce) doit être rendue impossible à violer par construction, pas confiée à la discipline humaine. Préférer des primitives à grand nonce (XChaCha20-Poly1305) quand la gestion d’état est difficile. Quand un compteur est nécessaire, le rendre inaccessible à la couche applicative et le faire gérer par la couche cryptographique.
Temps constant
La vérification du tag à l’ouverture doit s’effectuer en temps constant Temps constant Propriété d'une implémentation dont la durée d'exécution ne dépend pas des valeurs secrètes traitées, éliminant les canaux auxiliaires temporels. Elle est indispensable pour la comparaison de tags d'authentification et pour les opérations cryptographiques sensibles. ChaCha20-Poly1305 est naturellement en temps constant en logiciel, tandis qu'AES nécessite des instructions matérielles (AES-NI) pour atteindre cette propriété. : le temps d’exécution ne doit pas dépendre des valeurs comparées.
Pourquoi ? Parce qu’une comparaison naïve (octet par octet, retour dès la première différence) crée un canal caché temporel. Un adversaire qui peut mesurer le temps de réponse d’un serveur obtient une information : si le rejet arrive plus vite, les premiers octets du tag sont incorrects. Si le rejet prend un peu plus de temps, les premiers octets correspondent. En répétant suffisamment de tentatives, il peut reconstruire le tag valide octet par octet, sans jamais connaître la clé.
La défense est simple à énoncer : comparer les deux tags via un XOR de tous les octets, puis vérifier que le résultat cumulé est nul, sans branchement conditionnel anticipé.
La question du temps constant s’étend aussi à la primitive elle-même. ChaCha20 est conçu pour ne dépendre que d’additions, de rotations et de XOR, des opérations dont le temps d’exécution ne varie pas avec les données. AES en logiciel pur (sans instruction AES-NI) utilise des tables de substitution (S-box) accédées en mémoire : le cache processeur peut trahir quelles entrées ont été accédées, créant une fuite par canal auxiliaire de cache. Avec AES-NI, les instructions matérielles sont en temps constant par construction.
Choisir une primitive
Le choix entre AES-GCM et (X)ChaCha20-Poly1305 dépend du contexte de déploiement, pas d’une supériorité absolue de l’un sur l’autre.
AES-GCM est à privilégier quand l’environnement dispose d’AES-NI (serveurs x86-64, ARM Cortex-A avec ARMv8-A crypto). Les performances sont excellentes et le temps constant est garanti par le matériel. La contrainte principale est la gestion du nonce de 96 bits : un compteur bien géré est nécessaire dans les systèmes à fort débit ou distribués.
ChaCha20-Poly1305 est à privilégier dans les environnements sans accélération matérielle AES : mobiles anciens, microcontrôleurs, WASM, JavaScript natif. Les performances sont comparables ou meilleures, et le temps constant est assuré par construction algorithmique, sans dépendre du matériel. Le nonce de 192 bits de XChaCha20 simplifie considérablement la gestion en permettant la génération aléatoire sans limite pratique.
La agilité cryptographique Crypto-agilité Capacité d'un format ou d'un protocole à migrer vers de nouveaux primitifs cryptographiques sans casser les données existantes. Elle s'implémente typiquement par un octet de version en tête du chiffré, permettant de décoder les anciens enregistrements et de chiffrer les nouveaux avec l'algorithme courant. Elle est essentielle pour préparer une migration post-quantique. recommande de ne pas coupler le code applicatif à une primitive spécifique : encapsuler le choix dans une couche d’abstraction permet de migrer sans réécriture si une vulnérabilité est découverte.
Quiz
1. Pourquoi l'unicité du nonce est-elle critique, et non sa confidentialité ?
2. Que peut faire un adversaire qui observe deux messages AES-GCM chiffrés avec le même nonce et la même clé, dans le pire cas ?
3. Dans un système distribué où deux nœuds utilisent la même clé AES-GCM et chacun maintient un compteur local démarrant à zéro, quel est le problème ?
4. Pourquoi la comparaison de tags doit-elle s'effectuer en temps constant ?
Ce qu’il faut retenir
- Le nonce Nonce Valeur utilisée une seule fois avec une clé donnée. C'est l'unicité qui importe, non le secret : réutiliser un nonce avec la même clé brise complètement le schéma. Un nonce aléatoire de 192 bits (XChaCha20) offre une probabilité de collision négligeable, tandis qu'un compteur de 96 bits (AES-GCM, ChaCha20-Poly1305) exige une gestion rigoureuse pour ne jamais dépasser 2^32 messages par clé. Source : RFC 8439 voyage en clair. Ce qui importe n’est pas sa confidentialité, mais son unicité absolue par paire (clé, nonce).
- Réutiliser un nonce avec la même clé annule le flux de clé : . Si un message est connu, l’autre est récupérable.
- Dans AES-GCM, la réutilisation permet aussi de reconstruire la clé GHASH et de forger des tags valides pour n’importe quel message (Forbidden attack, 2016).
- AES-GCM avec un nonce de 96 bits exige un compteur bien géré en contexte distribué. La borne d’anniversaire limite l’usage des nonces aléatoires à environ messages par clé.
- XChaCha20-Poly1305 avec un nonce de 192 bits permet la génération aléatoire sans limite pratique, simplifiant la gestion dans les systèmes distribués ou sans état persistant.
- Une garantie qui repose sur une condition d’usage doit être rendue impossible à violer par construction, pas confiée à la discipline humaine.
- La vérification du tag doit s’effectuer en temps constant Temps constant Propriété d'une implémentation dont la durée d'exécution ne dépend pas des valeurs secrètes traitées, éliminant les canaux auxiliaires temporels. Elle est indispensable pour la comparaison de tags d'authentification et pour les opérations cryptographiques sensibles. ChaCha20-Poly1305 est naturellement en temps constant en logiciel, tandis qu'AES nécessite des instructions matérielles (AES-NI) pour atteindre cette propriété. pour supprimer le canal caché temporel.
- ChaCha20 est en temps constant par construction algorithmique. AES sans AES-NI peut créer des fuites de cache. AES-NI est en temps constant par le matériel.