
En cryptographie , un HMAC (parfois abrégé en code d'authentification de message par hachage à clé ou code d'authentification de message basé sur le hachage ) est un type spécifique de code d'authentification de message (MAC) utilisant une fonction de hachage cryptographique et une clé cryptographique secrète. Comme tout MAC, il permet de vérifier simultanément l' intégrité et l'authenticité des données d'un message. Un HMAC est un type de fonction de hachage à clé qui peut également être utilisé dans un schéma de dérivation de clé ou un schéma d'extension de clé.
HMAC peut assurer l'authentification à l'aide d'un secret partagé plutôt que de signatures numériques avec cryptographie asymétrique . Cette approche s'affranchit de la nécessité d'une infrastructure à clés publiques complexe en déléguant l'échange de clés aux parties communicantes, qui sont responsables de l'établissement et de l'utilisation d'un canal de confiance pour convenir de la clé avant toute communication.
Détails
Toute fonction de hachage cryptographique, telle que SHA-2 ou SHA-3 , peut être utilisée pour le calcul d'un HMAC ; l'algorithme MAC résultant est appelé HMAC- x , où x représente la fonction de hachage utilisée (par exemple HMAC-SHA256 ou HMAC-SHA3-512). La robustesse cryptographique du HMAC dépend de la robustesse cryptographique de la fonction de hachage sous-jacente, de la taille de son résultat de hachage, ainsi que de la taille et de la qualité de la clé.
HMAC utilise deux passes de calcul de hachage. Avant chaque passe, la clé secrète est utilisée pour générer deux clés : une interne et une externe. La première passe de l’algorithme de hachage produit un hachage interne à partir du message et de la clé interne. La seconde passe produit le code HMAC final à partir du hachage interne et de la clé externe. Ainsi, l’algorithme offre une meilleure immunité contre les attaques par extension de longueur .
Une fonction de hachage itérative (utilisant la construction de Merkle-Damgård ) divise un message en blocs de taille fixe et les traite à l'aide d'une fonction de compression . Par exemple, SHA-256 opère sur des blocs de 512 bits. La taille du résultat de HMAC est identique à celle de la fonction de hachage sous-jacente (256 bits pour SHA-256 et 512 bits pour SHA3-512), mais elle peut être tronquée si nécessaire.
HMAC ne chiffre pas le message. Ce dernier (chiffré ou non) doit être envoyé avec le hachage HMAC. Les parties possédant la clé secrète hachent à nouveau le message ; s’il est authentique, les hachages reçu et calculé correspondent.
La définition et l'analyse de la construction HMAC ont été publiées pour la première fois en 1996 dans un article de Mihir Bellare , Ran Canetti et Hugo Krawczyk [ qui ont également rédigé la RFC 2104 en 1997 L'article de 1996 définissait également une variante imbriquée appelée NMAC (Nested MAC). La publication FIPS 198 généralise et normalise l'utilisation des HMAC . HMAC est utilisé dans les protocoles IPsec , SSH et TLS , ainsi que pour les jetons Web JSON .
Définition
Cette définition est tirée de la RFC 2104 :
où
Fonction de hachageH | b, octets | L, octets |
|---|---|---|
| MD5 | 64 | 16 |
| SHA-1 | 64 | 20 |
| SHA-224 | 64 | 28 |
| SHA-256 | 64 | 32 |
| SHA-512/224 | 128 | 28 |
| SHA-512/256 | 128 | 32 |
| SHA-384 | 128 | 48 |
| SHA-512 | 128 | 64 |
| SHA3-224 | 144 | 28 |
| SHA3-256 | 136 | 32 |
| SHA3-384 | 104 | 48 |
| SHA3-512 | 72 | 64 |
out = H(in)L = length(out)b = H's internal block length | ||
Mise en œuvre
Le pseudocode suivant illustre la mise en œuvre possible de HMAC. La taille des blocs est de 512 bits (64 octets) lorsqu'on utilise l'une des fonctions de hachage suivantes : SHA-1, MD5 ou RIPEMD-128.
La fonction hmac prend en entrée : key : Bytes // Tableau d'octets message : Bytes // Tableau d'octets à hacher hash : Function // La fonction de hachage à utiliser (par exemple SHA-1) blockSize : Integer // La taille du bloc de la fonction de hachage (par exemple 64 octets pour SHA-1)// Calculer la clé de la taille du bloc clé_de_taille_bloc = calculerCléDeTailleBloc(clé, hachage, taille_bloc) o_key_pad ← block_sized_key xor [0x5c blockSize] // Touche extérieure rembourrée i_key_pad ← block_sized_key xor [0x36 blockSize] // Touche intérieure rembourréeretourner hash(o_key_pad ∥ hash(i_key_pad ∥ message))
La fonction computeBlockSizedKey prend en entrée : key : Bytes // Tableau d’octets hash : Function // La fonction de hachage à utiliser (par exemple SHA-1) blockSize : Integer // La taille du bloc de la fonction de hachage (par exemple 64 octets pour SHA-1)// Les clés plus longues que blockSize sont raccourcies par hachage si (length(key) > blockSize) alors clé = hachage(clé) // Les clés plus courtes que blockSize sont complétées à blockSize en ajoutant des zéros à droite si (length(key) < blockSize) alors retourner Pad(key, blockSize) // Compléter la clé avec des zéros pour qu'elle ait une longueur de blockSize octetstouche retour
Principes de conception
La conception de la spécification HMAC a été motivée par l'existence d'attaques ciblant des mécanismes plus simples de combinaison d'une clé et d'une fonction de hachage. Par exemple, on pourrait supposer que le même niveau de sécurité que celui offert par HMAC pourrait être atteint avec MAC = H ( clé | message ). Cependant, cette méthode présente une faille importante : avec la plupart des fonctions de hachage, il est facile d'ajouter des données au message sans connaître la clé et d'obtenir un autre MAC valide ( attaque par extension de longueur ). L'alternative, consistant à ajouter la clé via MAC = H ( message | clé ), souffre du problème suivant : un attaquant qui trouve une collision dans la fonction de hachage (sans clé) trouvera également une collision dans le MAC (car deux messages m1 et m2 produisant le même hachage fourniront la même condition initiale à la fonction de hachage avant le hachage de la clé ajoutée, et donc le hachage final sera identique). Utiliser MAC = H ( clé | message | clé ) est préférable, mais plusieurs articles de sécurité ont mis en évidence des vulnérabilités avec cette approche, même avec deux clés différentes.
Aucune attaque par extension n'a été découverte contre la spécification HMAC actuelle, définie comme H ( clé ∥ H ( clé ∥ message )), car l'application externe de la fonction de hachage masque le résultat intermédiaire du hachage interne. Les valeurs de ipad et opad ne sont pas critiques pour la sécurité de l'algorithme, mais ont été définies de manière à présenter une grande distance de Hamming entre elles, réduisant ainsi le nombre de bits communs entre les clés interne et externe. La réduction de sécurité de HMAC exige néanmoins qu'elles diffèrent d'au moins un bit.
La fonction de hachage Keccak , sélectionnée par le NIST comme gagnante du concours SHA-3 , n'a pas besoin de cette approche imbriquée et peut être utilisée pour générer un MAC en ajoutant simplement la clé au début du message, car elle n'est pas susceptible d'attaques par extension de longueur.
Sécurité
La robustesse cryptographique d'un HMAC dépend de la taille de la clé secrète utilisée et de la sécurité de la fonction de hachage sous-jacente. Il a été démontré que la sécurité d'une construction HMAC est directement liée aux propriétés de sécurité de la fonction de hachage employée. L'attaque la plus courante contre les HMAC consiste en une attaque par force brute visant à découvrir la clé secrète. Les HMAC sont nettement moins sensibles aux collisions que leurs algorithmes de hachage sous-jacents pris individuellement. En particulier, Mihir Bellare a démontré qu'un HMAC est une fonction pseudo-aléatoire (PRF) sous la seule hypothèse que la fonction de compression est une PRF. Par conséquent, HMAC-MD5 ne présente pas les mêmes faiblesses que MD5.
La RFC 2104 exige que « les clés de plus de B octets soient d'abord hachées à l'aide de H », ce qui peut engendrer une pseudo-collision déroutante : si la clé est plus longue que la taille du bloc de hachage (par exemple 64 octets pour SHA-1), alors le HMAC(k, m)hachage est calculé comme suitHMAC(H(k), m) : [formule mathématique manquante]. Cette propriété est parfois évoquée comme une faiblesse potentielle du HMAC dans le cadre du hachage de mots de passe : il a été démontré qu'il est possible de trouver une longue chaîne ASCII et une valeur aléatoire dont le hachage sera également une chaîne ASCII, et que les deux valeurs produiront le même résultat HMAC.
En 2006, Jongsung Kim , Alex Biryukov , Bart Preneel et Seokhie Hong ont démontré comment distinguer un HMAC utilisant des versions réduites de MD5 et SHA-1 ou des versions complètes de HAVAL , MD4 et SHA-0 d'une fonction aléatoire ou d'un HMAC utilisant une fonction aléatoire. Les discriminateurs différentiels permettent à un attaquant de concevoir une attaque par falsification contre un HMAC. De plus, les discriminateurs différentiels et rectangulaires peuvent conduire à des attaques par seconde préimage . Un HMAC utilisant la version complète de MD4 peut être falsifié grâce à cette information. Ces attaques ne contredisent pas la preuve de sécurité du HMAC, mais offrent un aperçu de son fonctionnement à partir des fonctions de hachage cryptographiques existantes.
En 2009, Xiaoyun Wang et al. ont présenté une attaque discriminante sur HMAC-MD5 sans utiliser de clés associées. Elle permet de distinguer une instance de HMAC avec MD5 d'une instance avec une fonction aléatoire en 2<sup> 97</sup> requêtes avec une probabilité de 0,87.
En 2011, la RFC 6151, document d'information, a été publiée afin de résumer les considérations de sécurité relatives à MD5 et HMAC-MD5. Concernant HMAC-MD5, la RFC indique que, bien que la sécurité de la fonction de hachage MD5 elle-même soit fortement compromise, les attaques actuellement connues contre HMAC-MD5 ne semblent pas révéler de vulnérabilité pratique lorsqu'il est utilisé comme code d'authentification de message. Elle précise toutefois que , pour la conception d'un nouveau protocole, il est déconseillé d'inclure une suite de chiffrement avec HMAC-MD5 .
En mai 2011, la RFC 6234 a été publiée détaillant la théorie abstraite et le code source des HMAC basés sur SHA.
Exemples
Voici quelques valeurs HMAC, en supposant un encodage ASCII 8 bits pour l'entrée et un encodage hexadécimal pour la sortie :
HMAC_MD5("clé", "Le rapide renard brun saute par-dessus le chien paresseux") = 80070713463e7749b90c2dc24911e275 HMAC_SHA1("clé", "Le rapide renard brun saute par-dessus le chien paresseux") = de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 HMAC_SHA256("clé", "Le rapide renard brun saute par-dessus le chien paresseux") = f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 HMAC_SHA512("clé", "Le rapide renard brun saute par-dessus le chien paresseux") = b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a