HMAC Expliqué
HMAC (Hash-Based Message Authentication Code) est un mécanisme permettant de vérifier à la fois l'intégrité et l'authenticité d'un message en utilisant une fonction de hachage cryptographique combinée à une clé secrète. Contrairement au hachage simple, que n'importe qui peut calculer, HMAC nécessite la connaissance de la clé secrète pour générer ou vérifier le code d'authentification.
Un hachage simple comme SHA256 vous indique qu'un message n'a pas été modifié, mais il ne prouve pas qui l'a créé. Un attaquant qui modifie le message peut simplement recalculer le hachage, et le destinataire n'a aucun moyen de détecter la falsification. HMAC résout ce problème en incorporant une clé secrète dans le calcul du hachage. Seule une personne possédant la clé peut produire un HMAC valide, ce qui le rend adapté à l'authentification de messages entre parties partageant un secret.
Comment Fonctionne HMAC
HMAC utilise deux passages de la fonction de hachage avec la clé secrète. L'algorithme est défini dans la RFC 2104 et fonctionne comme suit :
- La clé secrète est complétée à la taille du bloc de la fonction de hachage
- La clé complétée est combinée par XOR avec une constante de remplissage intérieure (ipad = 0x36 répété)
- Le message est ajouté à la clé intérieure complétée
- Le résultat est haché
- La clé complétée est combinée par XOR avec une constante de remplissage extérieure (opad = 0x5C répété)
- Le hachage de l'étape 4 est ajouté à la clé extérieure complétée
- Le résultat est haché à nouveau
HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
Cette approche à double hachage empêche les attaques par extension de longueur et garantit que même si la fonction de hachage sous-jacente présente des faiblesses, la construction HMAC reste sécurisée.
HMAC vs Hachage Simple
| Caractéristique | Hachage Simple (SHA256) | HMAC-SHA256 |
|---|---|---|
| Clé requise | Non | Oui |
| Vérification d'intégrité | Oui | Oui |
| Authentification | Non | Oui |
| Détection de falsification | Recalcul complet | Détection sans clé |
| Idéal pour | Sommes de contrôle de fichiers | Authentification d'API |
| Extension de longueur | Vulnérable | Résistant |
Cas d'Usage Courants
Authentification d'API — le client signe chaque requête avec HMAC en utilisant une clé secrète partagée. Le serveur recalcule le HMAC et le compare. S'ils correspondent, la requête est authentique.
Signature de Jetons JWT — bien que JWT utilise généralement HMAC ou une signature RSA plus simple, HMAC est un algorithme valide pour JWT (HS256, HS384, HS512).
Vérification de Webhooks — des services comme Stripe, GitHub et Slack signent les charges utiles des webhooks avec HMAC afin que vous puissiez vérifier qu'elles proviennent bien du service.
Jetons de Session — HMAC peut générer des jetons de session infalsifiables sans les stocker dans une base de données.
Exemples de Code
PHP
$secret = 'my-secret-key';
$message = 'message-to-authenticate';
// Générer un HMAC
$hmac = hash_hmac('sha256', $message, $secret);
echo $hmac;
// Vérifier un HMAC
$expected = hash_hmac('sha256', $message, $secret);
if (hash_equals($expected, $providedHmac)) {
echo 'Authentique';
}
Python
import hmac
import hashlib
secret = b'my-secret-key'
message = b'message-to-authenticate'
# Générer un HMAC
hmac_value = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(hmac_value)
# Vérifier un HMAC (comparaison en temps constant)
expected = hmac.new(secret, message, hashlib.sha256).digest()
received = bytes.fromhex(provided_hmac)
if hmac.compare_digest(expected, received):
print('Authentique')
JavaScript (Node.js)
const crypto = require('crypto');
const secret = 'my-secret-key';
const message = 'message-to-authenticate';
// Générer un HMAC
const hmac = crypto.createHmac('sha256', secret)
.update(message)
.digest('hex');
console.log(hmac);
// Vérifier
const expected = crypto.createHmac('sha256', secret)
.update(message)
.digest();
Algorithmes HMAC
HMAC peut utiliser n'importe quelle fonction de hachage cryptographique. Le nom de l'algorithme combine généralement « HMAC » avec le nom du hachage.
| Algorithme | Fonction de Hachage | Taille de Sortie |
|---|---|---|
| HMAC-MD5 | MD5 | 128 bits |
| HMAC-SHA1 | SHA-1 | 160 bits |
| HMAC-SHA256 | SHA-256 | 256 bits |
| HMAC-SHA512 | SHA-512 | 512 bits |
| HMAC-SHA3-256 | SHA3-256 | 256 bits |
Utilisez HMAC-SHA256 par défaut. HMAC-MD5 et HMAC-SHA1 sont dépréciés pour les applications sensibles à la sécurité.
Considérations de Sécurité
Taille de clé — la clé doit être au moins aussi longue que la sortie du hachage. Pour HMAC-SHA256, utilisez une clé d'au moins 32 octets (256 bits). Les clés plus longues sont hachées à la taille du bloc.
Confidentialité de la clé — la sécurité de HMAC dépend entièrement du secret de la clé. Utilisez un système de gestion de clés ou des variables d'environnement. Ne codez jamais les clés en dur dans le code source.
Comparaison en temps constant — comparez toujours les valeurs HMAC à l'aide d'une fonction de comparaison en temps constant comme hash_equals() en PHP ou hmac.compare_digest() en Python. Une attaque temporelle pourrait autrement révéler le HMAC correct octet par octet.
Attaques par rejeu — HMAC seul ne prévient pas les attaques par rejeu. Incluez un timestamp ou un nonce dans le message signé et vérifiez-le sur le serveur.
Outil en Ligne
L'outil Générateur HMAC sur Help2Code calcule les valeurs HMAC avec votre choix d'algorithme et de clé secrète. Utilisez-le pour tester des implémentations HMAC ou générer des vecteurs de test pendant le développement.
Conclusion
HMAC fournit une authentification de message en utilisant une clé secrète partagée et une fonction de hachage cryptographique. Il est essentiel pour la sécurité des API, la vérification des webhooks, et tout scénario où vous devez vérifier à la fois l'intégrité et l'authenticité d'un message. Utilisez HMAC-SHA256 avec une clé secrète forte et comparez toujours les valeurs HMAC à l'aide de fonctions en temps constant.