Tous les articles

HMAC : en quoi un hachage avec clé diffère d'un hachage classique

Stripe, très utilisé par les startups françaises, signe chaque webhook avec HMAC-SHA256 : l'en-tête Stripe-Signature contient un horodatage et une signature que le serveur destinataire doit recalculer localement à partir du corps brut de la requête et de sa clé secrète, puis comparer à ce qui a été reçu. Si les deux ne correspondent pas, la requête ne vient pas réellement de Stripe et ne doit surtout pas être traitée comme un événement de paiement légitime.

Pourquoi il faut une clé secrète, pas seulement un hachage

Un hachage classique comme SHA-256 prouve seulement que les données n'ont pas été altérées en transit, pas qui les a envoyées. Si un serveur se contentait de hacher le corps du webhook et de le comparer à un hachage inclus dans la requête, un attaquant pourrait forger sa propre charge utile et y joindre un hachage correspondant. HMAC résout ce problème en mélangeant une clé secrète connue uniquement de l'expéditeur et du destinataire : sans elle, produire une signature valide est infaisable, même si l'attaquant connaît exactement quelle fonction de hachage est utilisée.

Pourquoi ce n'est pas juste "hacher la clé plus le message"

Concaténer naïvement la clé et le message avant de hacher (par exemple hash(clé + message)) est vulnérable aux attaques par extension de longueur sur certaines fonctions de hachage — un attaquant peut parfois ajouter des données et calculer un nouveau hachage valide sans connaître la clé entière. HMAC utilise une construction spécifique avec double hachage et bourrage interne/externe qui ferme complètement cette classe d'attaque.

Où HMAC apparaît encore

Au-delà de la signature des webhooks, HMAC authentifie les requêtes API et constitue le cœur de l'algorithme TOTP — celui qui génère les codes à six chiffres des applications d'authentification.

Pourquoi c'est utile

  • Vérifier l'authenticité de webhooks provenant de prestataires de paiement ou d'autres services tiers.
  • Signer des requêtes API sans jamais transmettre la clé secrète elle-même sur le réseau.
  • Comprendre le fonctionnement interne des codes TOTP et des jetons de session.

Comparaison en temps constant

Comparer une signature reçue à celle attendue avec un simple === est dangereux : cet opérateur s'arrête généralement au premier octet différent, et le temps d'exécution de la comparaison révèle à l'attaquant combien des premiers octets il a devinés correctement. Un gestionnaire de webhook fiable utilise toujours une fonction de comparaison en temps constant — comme hash_equals en PHP ou crypto.timingSafeEqual en Node.js — qui vérifie tous les octets quel que soit l'emplacement de la première différence.

Essayer l'outil