Prouver qu’un message vient du bon secret
- Accueil
- Cryptographie
- Prouver qu’un message vient du bon secret
Prouver qu’un message vient du bon secret
Section intitulée « Prouver qu’un message vient du bon secret »Le chiffrement cache un message ; il ne dit rien de son origine ni de son intégrité. Pour savoir qu’un message vient de quelqu’un qui détient une clé secrète et qu’il n’a pas été modifié, on utilise un MAC (Message Authentication Code, code d’authentification de message). Ce chapitre présente le principe, les constructions à partir de fonctions de hachage et de chiffrements par blocs, les MAC spécialisés, et insiste sur les deux endroits où tout se joue en pratique : ce que l’on authentifie exactement, et la manière de comparer l’étiquette.
Deux amis conviennent d’une marque secrète pour signer leurs petits mots : n’importe qui peut lire le mot, mais seuls eux deux savent y ajouter la bonne marque. Ce chapitre présente cette manière de prouver qu’un message vient bien de quelqu’un qui connaît le secret, et qu’il n’a pas été modifié en chemin.
→ Lire l’explication complète de la marmotte
Authentifier sans clé publique
Section intitulée « Authentifier sans clé publique »Un MAC repose sur une clé partagée K connue de l’émetteur et du récepteur. L’émetteur calcule une étiquette (tag) t = MAC(K, m), courte, typiquement 16 ou 32 octets, et l’envoie avec le message. Le récepteur recalcule l’étiquette et compare : c’est la vérification. La sécurité attendue s’appelle l’infalsifiabilité sous attaque à message choisi : même après avoir obtenu les étiquettes de messages de son choix, un attaquant ne doit pas pouvoir produire une étiquette valide pour un message nouveau. Cela couvre la modification d’un message existant comme la fabrication d’un message de toutes pièces.
Le MAC authentifie exactement ce qu’on lui donne, rien de plus. Les métadonnées comptent autant que le corps : en-têtes, identifiant de destinataire, version de protocole, type de message. Si l’étiquette porte sur le corps d’une requête et pas sur le chemin /virement/compte/12345, l’attaquant change le compte en laissant l’étiquette intacte. La représentation doit aussi être sans ambiguïté : authentifier la concaténation de « montant » et « devise » rend identiques "10" + "0EUR" et "100" + "EUR". On encode chaque champ avec sa longueur, ou dans un format canonique.
Un MAC valide ne dit rien de la fraîcheur. Un message authentique intercepté puis renvoyé dix fois porte dix fois une étiquette valide : c’est le rejeu. La parade consiste à inclure dans les données authentifiées un compteur monotone, un horodatage avec fenêtre d’acceptation, ou un identifiant unique mémorisé par le récepteur. Encore faut-il vérifier l’étiquette : un webhook reçu sans vérification de signature obéit à quiconque connaît son adresse, ce qui fait beaucoup de monde pour un secret.
La PRF (Pseudo-Random Function, fonction pseudo-aléatoire) est une notion voisine et plus forte : une fonction à clé dont les sorties sont indistinguables de valeurs aléatoires pour qui ignore la clé. Toute PRF à sortie suffisamment longue est un bon MAC ; l’inverse est faux, car un MAC peut laisser fuir de l’information sur le message tout en restant infalsifiable. HMAC est utilisé comme PRF dans de nombreux protocoles, notamment pour dériver des clés avec HKDF. Une fonction de hachage seule n’est ni l’un ni l’autre : sans clé, tout le monde la calcule.
Constructions à partir de hash
Section intitulée « Constructions à partir de hash »HMAC (Hash-based MAC), défini par la RFC 2104 en 1997 et normalisé par FIPS 198-1, est la construction la plus répandue. Sa formule est HMAC(K, m) = H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ m)), où ipad et opad sont deux constantes. Les deux passes de hachage imbriquées ne sont pas une coquetterie.
Pourquoi les concaténations naïves échouent tient en deux cas. Le préfixe secret, H(K ‖ m), est cassé avec MD5, SHA-1 et la famille SHA-2 par l’extension de longueur : connaissant l’empreinte de K ‖ m et la longueur de K, l’attaquant reprend le calcul là où il s’est arrêté et obtient l’empreinte valide de K ‖ m ‖ rembourrage ‖ suffixe de son choix, sans connaître K. Un paramètre &admin=1 ajouté à une requête signée de cette façon passe la vérification. Le suffixe secret, H(m ‖ K), résiste à cette attaque mais devient vulnérable dès qu’une collision est trouvée sur H : deux messages qui collisionnent avant l’ajout de la clé ont la même étiquette, et la collision se cherche hors ligne, sans interroger personne. HMAC évite ces deux défauts et reste sûr même avec des fonctions dont la résistance aux collisions est compromise ; HMAC-MD5 n’est pas cassé en tant que MAC, ce qui ne constitue pas une invitation à l’employer.
Le choix du hash se fait aujourd’hui entre SHA-256, SHA-512 et SHA-3. Les fonctions SHA-3 ne souffrent pas de l’extension de longueur, et le NIST définit dans la publication SP 800-185 KMAC, un MAC natif fondé sur Keccak qui n’a pas besoin de la double passe. La clé doit avoir au moins la taille de la sortie visée, 32 octets pour HMAC-SHA-256, et provenir d’un générateur cryptographique. Une clé ne sert qu’à un usage et un domaine : la même clé pour authentifier des jetons de session et des liens de réinitialisation permet de présenter l’un comme l’autre. On sépare les domaines en dérivant des clés distinctes, ou en préfixant chaque message d’une étiquette de contexte.
Constructions à partir de blocs
Section intitulée « Constructions à partir de blocs »CBC-MAC chiffre le message en mode CBC (Cipher Block Chaining) avec un vecteur d’initialisation nul et garde le dernier bloc comme étiquette. Il est sûr pour des messages de longueur fixe, et seulement pour eux. Avec des messages de longueur variable, la falsification est immédiate : si t est l’étiquette du message d’un bloc m, alors t est aussi l’étiquette du message de deux blocs m ‖ (m ⊕ t), puisque le second chiffrement reçoit en entrée t ⊕ m ⊕ t = m. Un vecteur d’initialisation aléatoire casse aussi la construction, car l’attaquant qui le contrôle modifie librement le premier bloc.
CMAC, normalisé par le NIST dans la publication SP 800-38B, corrige ces défauts en combinant le dernier bloc avec une sous-clé dérivée de K, différente selon que le message est complet ou rembourré. AES-CMAC est employé dans des contextes contraints, comme certains protocoles de cartes à puce ou de réseaux embarqués.
GMAC est le mode GCM (Galois/Counter Mode) employé sans rien chiffrer : il authentifie des données à l’aide d’un hachage universel dans un corps de Galois. Ses conditions d’usage sont strictes : un nonce unique par message sous une même clé. Réutiliser un nonce avec GMAC ou GCM permet de retrouver la sous-clé d’authentification et de forger ensuite des étiquettes à volonté.
MAC spécialisés
Section intitulée « MAC spécialisés »Poly1305, conçu par Daniel J. Bernstein en 2005, est un MAC à clé à usage unique : il évalue un polynôme modulo 2^130 − 5 à partir des blocs du message et produit une étiquette de 16 octets. Utilisé deux fois avec la même clé, il livre de quoi la retrouver. Dans ChaCha20-Poly1305 (RFC 8439), la clé Poly1305 est dérivée pour chaque message à partir de la clé principale et du nonce, ce qui respecte la règle sans effort de l’utilisateur, à condition que le nonce soit unique.
SipHash, publié en 2012 par Aumasson et Bernstein, vise un autre problème : la protection de tables de hash. Un serveur qui range des clés fournies par les clients dans une table de hachage avec une fonction prévisible peut être saturé par un attaquant qui envoie des milliers de clés tombant dans la même case, ce qu’on appelle l’inondation de hachage. SipHash, MAC rapide sur messages courts avec une clé secrète tirée au démarrage, rend ces collisions imprévisibles. Python l’utilise pour le hachage des chaînes depuis la version 3.4, et la table de hachage par défaut de Rust aussi. Sa sortie de 64 bits le réserve à cet usage, pas à l’authentification de messages réseau.
La performance départage les autres choix. Sur un processeur doté d’instructions AES, GMAC et AES-CMAC sont très rapides ; sans elles, Poly1305 et les fonctions de la famille BLAKE l’emportent. HMAC-SHA-256 reste parfaitement acceptable pour l’immense majorité des API, où le coût du MAC disparaît devant celui du réseau.
Exemples et ateliers
Section intitulée « Exemples et ateliers »Vérification HMAC en temps constant. En Python :
import hmac, hashlib
def verifier(cle: bytes, message: bytes, etiquette_recue: bytes) -> bool: attendue = hmac.new(cle, message, hashlib.sha256).digest() return hmac.compare_digest(attendue, etiquette_recue)hmac.compare_digest examine toujours tous les octets. Une comparaison avec == s’arrête au premier octet différent : en mesurant le temps de réponse sur de nombreuses requêtes, un attaquant détermine quel préfixe est correct et reconstruit l’étiquette octet par octet. Les équivalents existent partout : crypto.timingSafeEqual en Node.js, hmac.Equal en Go, MessageDigest.isEqual en Java.
Modifier un champ non authentifié, puis corriger. Une API reçoit {"montant": 100, "compte": "FR76..."} avec un en-tête X-Signature qui ne couvre que le montant. Changer le compte ne déclenche aucune erreur. La correction consiste à authentifier une sérialisation canonique de l’objet complet, avec la méthode HTTP, le chemin et un horodatage, puis à refuser toute requête dont un champ n’était pas couvert.
MAC et signature sur un même message. Le même message reçoit une étiquette HMAC-SHA-256 de 32 octets et une signature Ed25519 de 64 octets. L’étiquette ne se vérifie qu’avec la clé secrète, donc par quelqu’un qui pourrait aussi l’avoir produite. La signature se vérifie avec la clé publique, par n’importe qui, sans pouvoir être imitée. Seule la seconde permet à un tiers de trancher un litige ; les signatures sont présentées dans la page sur la signature comme preuve publique.
Rejeu sans compteur. Une commande « ouvrir la porte », authentifiée par HMAC et sans compteur, est enregistrée par un récepteur radio bon marché puis renvoyée le lendemain : la porte s’ouvre, convaincue d’obéir à son propriétaire. Ajouter un compteur incrémenté et mémorisé par la serrure, inclus dans les données authentifiées, suffit à rejeter la copie.
Pièges classiques
Section intitulée « Pièges classiques »Comparer les étiquettes avec == ou strcmp ouvre la fuite temporelle décrite plus haut. Réutiliser une clé de MAC pour chiffrer crée des interactions imprévues entre les deux primitives : le cas classique est celui de CBC et CBC-MAC avec la même clé, qui casse l’authentification. Authentifier une représentation ambiguë autorise le déplacement de frontières entre champs. Laisser l’attaquant choisir l’algorithme de MAC, comme dans les jetons JWT (JSON Web Token) qui acceptaient "alg": "none" ou confondaient HS256 et RS256, revient à lui laisser choisir la serrure ; ces attaques sont détaillées dans la page sur JWS. Le chiffrement authentifié, qui combine chiffrement et MAC correctement, est présenté dans la page sur le chiffrement qui ne suffit pas seul.
À ne pas confondre
Section intitulée « À ne pas confondre »MAC et signature : le MAC repose sur un secret partagé et n’offre pas la non-répudiation, puisque chaque détenteur de la clé peut produire l’étiquette. PRF et hash : la PRF a une clé et des sorties imprévisibles pour qui l’ignore, le hash est public. GMAC et GCM : GMAC n’authentifie que des données en clair, GCM chiffre et authentifie. Authentification du message et anti-rejeu : la première garantit l’origine et l’intégrité, le second la fraîcheur, et il faut un mécanisme explicite pour l’obtenir.
🐝 Ce qui arrive si on s’en passe
Section intitulée « 🐝 Ce qui arrive si on s’en passe »Sans vérification stricte de l’étiquette, un champ non authentifié devient un bouton de réglage offert à l’attaquant : montant, destinataire ou droit d’accès se modifient en transit sans que rien ne proteste. Une comparaison faite avec == laisse fuir, par la durée de la réponse, la bonne étiquette octet après octet. Sans compteur, un ordre authentique intercepté se rejoue autant de fois que souhaité, chaque fois parfaitement valide. Et comme la clé est partagée, aucun journal ne permet d’établir lequel des détenteurs a produit un message donné : le MAC atteste une origine commune, pas une personne, ce qui complique singulièrement toute contestation ultérieure.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Un code d’authentification de message, souvent abrégé MAC, sert à vérifier qu’un message vient de quelqu’un qui connaît une clé secrète partagée et qu’il n’a pas été modifié. L’expéditeur calcule, à partir de la clé et du message, une courte valeur appelée étiquette, et l’envoie avec le message. Le destinataire refait le même calcul avec la même clé et compare. Si les deux valeurs sont identiques, le message est accepté ; sinon, il est rejeté. Sans la clé, un attaquant ne peut pas fabriquer une étiquette valide, même après en avoir observé beaucoup. Plusieurs constructions existent : celles fondées sur une fonction de hachage, comme HMAC, celles fondées sur un chiffrement par blocs, et des algorithmes spécialisés très rapides. Les assemblages naïfs, comme hacher la clé collée au message, peuvent être cassés. La comparaison finale doit toujours prendre le même temps : si elle s’arrête au premier octet différent, un attaquant peut mesurer la durée et deviner l’étiquette octet par octet. Le calcul doit aussi porter sur une représentation sans ambiguïté du message et de ses informations annexes. Enfin, une étiquette valide ne prouve pas que le message est nouveau : un attaquant peut renvoyer un ancien message authentique. Pour l’empêcher, on ajoute un compteur ou une date. Contrairement à une signature, tous ceux qui détiennent la clé peuvent produire l’étiquette.
À lire aussi
- Condensés cryptographiques : propriétés, constructions et famillesPrésenter le hachage comme une primitive sans clé par défaut, utile pour l’intégrité et la construction d’autres schémas, mais impropre au stockage direct des mots de passe.
- Transformer mots de passe et secrets applicatifs en clésDistinguer mot de passe, clé, token et secret d’application, puis présenter les fonctions de dérivation adaptées aux usages humains et machine.
- Transformer un bloc en chiffrement de messageExpliquer les modes opératoires, leurs fuites et leurs exigences de paramètres, puis orienter vers les modes authentifiés pour les usages modernes.
- Hachage dans les systèmes: intégrité, arbres et preuvesRegrouper les usages systémiques du hachage: empreintes, arbres, preuves, déduplication, chaînes d’intégrité et limites de sécurité.
Pages voisines
La citent
- Condensés cryptographiques : propriétés, constructions et familles
- Comprendre la cryptanalyse sans perdre le fil pratique
- Authentification défi-réponse, rejeu, relais et attaque hors ligne
- Comment observer un LLM en production
- Confidentialité différentielle pour télémétrie produit
- Routage interne, redistribution et stabilité
Prouver qu’un message vient du bon secret
Elle cite
- Lien dans les deux sens :JWS : signer et sécuriser vos échanges JSON
- Chiffrer et authentifier en une seule construction
- Créer, vérifier et utiliser les clés dès le départ
- Signer numériquement : preuve publique, politiques de vérification
- Comment bloquer un webhook forgé sans signature vérifiée
- Formats, bibliothèques et API : rendre la crypto utilisable
: les deux pages se citent l’une l’autre.
