Générateur HMAC et vérificateur de signature

Calcule HMAC-SHA-1, SHA-256, SHA-384 et SHA-512 à partir d’un message et d’une clé, et identifie de laquelle provient une signature donnée.

Message
HMAC-SHA-1
HMAC-SHA-256
HMAC-SHA-384
HMAC-SHA-512

Saisissez une clé pour calculer les signatures.

Ce que fait cet outil

HMAC transforme un message et un secret partagé en une courte signature. Quiconque détient le même secret peut la recalculer et voir si le message est arrivé inchangé et s’il vient de quelqu’un qui connaît lui aussi le secret. Cet outil calcule les quatre variantes courantes d’un coup et, à partir d’une signature qu’on vous a envoyée, vous dit laquelle l’a produite.

Ce second sens est généralement la raison pour laquelle on arrive ici. Un webhook échoue à la vérification, et la vraie question n’est pas « cette signature est-elle valide » mais « laquelle des quelques choses plausibles est-ce que je fais autrement que l’expéditeur ».

La clé est l’endroit où cela dérape

HMAC signe des octets avec des octets. Le message est en général évident — le corps brut de la requête — mais la clé presque jamais, car un secret arrive sous forme de chaîne et une chaîne n’est pas des octets tant que vous n’avez pas décidé comment la lire :

a3f2  ->  61 33 66 32   4 bytes   en texte
a3f2  ->  a3 f2         2 bytes   en hex

Les deux lectures sont légitimes, les deux produisent une signature parfaitement bien formée, et les deux signatures n’ont rien en commun. Rien ne vous prévient : pas d’erreur, pas de plainte sur la longueur, juste une valeur qui ne correspond pas à celle calculée par l’expéditeur. C’est pourquoi l’encodage de la clé est ici un choix visible plutôt qu’une supposition — quand une signature ne correspond pas, c’est la première chose à basculer.

À titre indicatif : un secret avec un préfixe du genre whsec_ ou une suite de lettres et de chiffres mêlant majuscules et minuscules se lit normalement en texte ; une chaîne de exactement 32 ou 64 caractères n’utilisant que 0-9 et a-f est généralement de l’hexadécimal ; et une chaîne finissant par = est presque certainement du Base64. Mais consultez la documentation de l’expéditeur plutôt que la forme, car la forme n’est pas une preuve.

Le message doit être les octets exacts

L’autre moitié d’une non-concordance, c’est le message. HMAC est défini sur des octets : tout ce qui change les octets change complètement la signature — pas de demi-point, pas de presque bon.

  • Re-sérialiser le JSON. Analyser un corps puis le re-générer peut réordonner les clés, changer les espaces ou normaliser les nombres. Signez et vérifiez le corps brut reçu, jamais une copie passée par un aller-retour.
  • Un saut de ligne final. Certains outils en ajoutent un lorsqu’on enregistre le corps dans un fichier ; c’est un octet, et cela change tout.
  • L’encodage des caractères. Un corps contenant du texte non ASCII doit être lu avec le même encodage des deux côtés — en pratique UTF-8.
  • Compression ou intergiciel. Si quelque chose devant votre gestionnaire décompresse ou réécrit le corps, vérifiez avant que cela n’arrive, pas après.

Beaucoup de fournisseurs ne signent d’ailleurs pas le seul corps. Stripe signe un horodatage et le corps joints par un point ; AWS signe une requête canonique construite à partir de la méthode, du chemin, des en-têtes et d’un hachage de la charge utile. Si la vérification échoue face au corps simple, la chaîne signée n’est probablement pas le corps simple — c’est documenté côté expéditeur et cela vaut la peine d’être lu avant de déboguer plus loin.

Pourquoi SHA-1 est proposé ici et pas dans l’outil de hachage

L’outil de hachage marque SHA-1 comme cassé. Celui-ci liste HMAC-SHA-1 sans avertissement, et c’est délibéré, non un oubli.

SHA-1 est inutilisable pour les signatures et les certificats parce qu’on peut construire des collisions : deux documents différents peuvent être amenés à partager une empreinte. HMAC ne dépend pas de cette propriété. Sa sécurité repose sur la clé secrète, et la construction — hacher le message deux fois, la clé étant mêlée aux deux passes — tient même quand le hachage sous-jacent est faible face aux collisions. HMAC-SHA-1 reste solide et c’est ce qu’emploient OAuth 1.0a et l’ancienne signature AWS ; un outil qui refuserait de le calculer serait donc simplement moins utile sans être plus sûr.

Pour toute nouveauté, SHA-256 est le choix raisonnable. Des empreintes plus longues ne sont pas significativement plus fortes ici — le plafond de sécurité est la clé, pas la longueur de l’empreinte — donc SHA-384 et SHA-512 ne valent d’être choisis que si quelque chose avec quoi vous devez interopérer les réclame.

Comparer les signatures sans danger

Cette page compare avec une comparaison de chaînes ordinaire, ce qui convient ici : vous détenez vous-même la clé, il n’y a donc rien à divulguer. Dans un serveur qui vérifie une requête entrante, cela ne convient pas. Une comparaison ordinaire s’arrête au premier octet différent : le temps qu’elle met révèle quelle part d’une supposition était correcte, et un attaquant capable d’envoyer beaucoup de requêtes peut retrouver une signature valide octet par octet.

Utilisez la comparaison à temps constant fournie par votre plateforme — crypto.timingSafeEqual en Node, hmac.compare_digest en Python, hash_equals en PHP — sur les octets bruts plutôt que sur des chaînes hexadécimales. À cela s’ajoute : comparez à une signature que vous avez calculée vous-même plutôt que de faire confiance à un algorithme nommé dans la requête, et rejetez un message dont l’horodatage est loin de maintenant, pour qu’une ancienne signature valide ne puisse pas être rejouée.

HMAC n’est ni un hachage ni une signature

Trois choses se confondent ici, et la différence compte pour ce que l’on peut affirmer ensuite :

  • Un hachage prend un message et produit une empreinte. N’importe qui peut la calculer : il prouve donc que le message n’a pas changé par accident, pas qu’il vienne de quelqu’un en particulier.
  • Un HMAC prend un message et un secret partagé. Les deux parties détiennent la même clé : il prouve donc que l’expéditeur connaissait le secret. Il ne peut pas prouver laquelle des deux a envoyé, puisque l’une comme l’autre aurait pu le produire.
  • Une signature utilise une clé privée que seul l’expéditeur détient, et une clé publique avec laquelle chacun peut vérifier. C’est ce qui donne la non-répudiation : l’expéditeur ne peut pas la nier ensuite.

HMAC est donc l’outil qu’il faut entre deux systèmes qui partagent déjà un secret — webhooks, API internes, jetons de session — et le mauvais outil quand il faut prouver à un tiers qui a envoyé quelque chose. Notez aussi qu’il authentifie mais ne dissimule pas : le message circule en clair, et HMAC ne dit rien de la confidentialité.

Questions fréquentes

Ma signature ne correspond pas. Que vérifier en premier ?
L’encodage de la clé, puis les octets du message. Un secret qui ressemble à de l’hexadécimal est souvent voulu comme tel et non comme du texte, et les deux produisent des signatures totalement différentes sans erreur ni d’un côté ni de l’autre. Ensuite, assurez-vous de signer le corps brut tel que reçu et non une copie re-sérialisée.
Pourquoi SHA-1 est-il proposé ici alors que l’outil de hachage le dit cassé ?
Parce que HMAC ne repose pas sur la résistance aux collisions, la propriété que SHA-1 a perdue. Sa sécurité vient de la clé. HMAC-SHA-1 reste solide et employé par OAuth 1.0a et l’ancienne signature AWS, même si SHA-256 est le bon choix par défaut pour toute nouveauté.
Une empreinte plus longue est-elle plus sûre ?
Pas de façon significative. La force d’un HMAC est bornée par le secret, pas par la longueur de l’empreinte : SHA-512 n’est donc pas quatre fois meilleur que SHA-256. Prenez celui qu’attend l’autre partie.
Quelle différence entre HMAC et une signature numérique ?
HMAC emploie un secret que les deux côtés connaissent : il prouve que l’expéditeur connaissait le secret, mais pas quel côté a envoyé. Une signature numérique emploie une clé privée que seul l’expéditeur détient, si bien qu’un tiers peut la vérifier et que l’expéditeur ne peut pas la nier. S’il vous faut cette dernière propriété, HMAC n’est pas le bon outil.
Dois-je comparer les signatures avec === ?
Pas dans un serveur. Une comparaison ordinaire revient dès que les octets diffèrent, et ce temps divulgue quelle part d’une signature devinée était juste. Utilisez la comparaison à temps constant de votre plateforme sur les octets bruts. Sur cette page cela n’a pas d’importance, puisque vous détenez déjà la clé.
Ma clé est-elle envoyée quelque part ?
Non. Tout est calculé dans votre navigateur avec l’API Web Crypto ; le message et la clé ne quittent jamais votre appareil.