Sådan bruger du værktøjet
- Vælg algoritmen. HMAC-SHA256 er valgt som standard, og det er den, de fleste webhooks og API'er bruger.
- Indtast nøglen under Hemmelig nøgle, og sæt Nøgleformat til Tekst (læses som UTF-8), Hex eller Base64. Brug Hex eller Base64, når nøglen består af rå bytes og ikke er en adgangskodelignende streng.
- Skriv eller indsæt beskeden, skift inputtet til Hex for rå bytes, eller klik på Åbn fil. HMAC-værdien opdateres, mens du skriver.
- Vælg hex (små bogstaver), HEX (store bogstaver) eller Base64 under Output som, og kopiér resultatet, eller indsæt en modtaget signatur under Sammenlign med for at se Stemmer overens eller Stemmer ikke overens.
Sådan fungerer HMAC
HMAC (hash-based message authentication code, RFC 2104) kombinerer en kryptografisk hashfunktion med en hemmelig nøgle. Kun den, der kender nøglen, kan beregne den rigtige værdi for en besked, så en HMAC, der stemmer overens, beviser to ting på én gang: Beskeden er ikke blevet ændret, og den kommer fra en, der har nøglen.
Konstruktionen er H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ message)). Nøglen hashes først, hvis den er længere end hashfunktionens blokstørrelse (64 bytes for MD5, SHA-1 og SHA-256, 128 for SHA-384 og SHA-512). Derefter udfyldes den med nuller til den størrelse og XOR'es med ipad (bytes med værdien 0x36) til en indre hashberegning over beskeden og med opad (bytes med værdien 0x5c) til en ydre hashberegning over det indre resultat. En naiv SHA-256(key ‖ message) har ingen ydre hashberegning, så alle, der ser én MAC-værdi, kan tilføje data til beskeden og beregne en gyldig ny MAC-værdi uden nøglen (et såkaldt length extension-angreb).
Outputtet har samme længde som den underliggende hashfunktion: 32 bytes, eller 64 hextegn, for HMAC-SHA256. RFC 2104 anbefaler en nøgle, der er mindst lige så lang, og generatoren til tilfældig Base64 laver egnede nøgler.
Hvor HMAC-signaturer bruges
- GitHub-webhooks. Headeren
X-Hub-Signature-256består afsha256=efterfulgt af HMAC-SHA256 i hex af anmodningens rå body med webhookens hemmelighed som nøgle. Du kan indsætte hele headerværdien under Sammenlign med; præfiksetsha256=ignoreres. - Stripe-webhooks. Headeren
Stripe-Signatureindeholder et tidsstempeltog en signaturv1: HMAC-SHA256 i hex af tidsstemplet, et punktum og den rå body, hvor endpointets hemmelighed (whsec_...) bruges som nøgle i tekstform. - Shopify-webhooks.
X-Shopify-Hmac-Sha256indeholder HMAC-SHA256 af den rå body i Base64 med appens client secret som nøgle, så vælg Base64 som output, eller indsæt headerværdien under Sammenlign med. - AWS Signature Version 4. Signeringsnøglen udledes ved at kæde HMAC-SHA256-beregninger sammen: først datoen med
AWS4plus den hemmelige adgangsnøgle som nøgle, derefter regionen, tjenesten ogaws4_request, hver med det forrige resultat som nøgle. Sæt Nøgleformat til Hex for at bruge outputtet fra ét trin i det næste. - JSON Web Tokens. HS256, HS384 og HS512 er HMAC-SHA256, -384 og -512 over den kodede header, et punktum og den kodede payload. Tokenets tredje del er denne HMAC i URL-sikker Base64, som Sammenlign med accepterer, som den er. JWT-dekoderen verificerer hele tokens.
Beregn altid HMAC over den rå body, præcis som den blev modtaget. Hvis du fortolker JSON og serialiserer den igen, ændres mellemrum eller rækkefølgen af JSON-nøglerne, og selv ét ekstra linjeskift giver en helt anden HMAC.
HMAC i kode
# Python
import hmac, hashlib
sig = hmac.new(b'key', b'message', hashlib.sha256).hexdigest()
hmac.compare_digest(sig, received) # sammenligning i konstant tid
// Node.js
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', 'key').update('message').digest('hex');
// timingSafeEqual kaster en fejl, hvis længderne er forskellige, så tjek dem først
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(received));
// PHP: beskeden kommer før nøglen
$sig = hash_hmac('sha256', 'message', 'key');
hash_equals($sig, $received);
# OpenSSL: en tekstnøgle og derefter den samme nøgle angivet som hex
printf '%s' 'message' | openssl dgst -sha256 -hmac 'key'
printf '%s' 'message' | openssl dgst -sha256 -mac HMAC -macopt hexkey:6b6579
# Testvektor: nøgle "key", besked "The quick brown fox jumps over the lazy dog"
# HMAC-SHA256 = f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
Når du verificerer en signatur i din egen kode, skal du bruge en sammenligning i konstant tid som i eksemplerne ovenfor. En almindelig == stopper ved det første tegn, der er forskelligt, og den tidsforskel kan lade en angriber finde en gyldig signatur byte for byte. Ved skemaer med tidsstempel, som Stripes, bør du også afvise anmodninger, hvis tidsstempel er mere end et par minutter gammelt; det forhindrer genafspilning (replay).
Ofte stillede spørgsmål
Er HMAC-MD5 og HMAC-SHA1 stadig sikre?
Kollisionsangreb bryder MD5 og SHA-1 som almindelige hashfunktioner, men de giver ingen praktisk måde at forfalske en HMAC på, da den afhænger af andre egenskaber ved hashfunktionen og af en hemmelig nøgle (RFC 6151 behandler HMAC-MD5). Integrationer, der kræver dem, som TOTP-koder baseret på HMAC-SHA1, kan du roligt beholde. Brug HMAC-SHA256 til nye løsninger.
Hvorfor stemmer min HMAC ikke overens med webhook-signaturen?
De typiske årsager er, at fortolket og genserialiseret JSON hashes i stedet for den rå body, et afsluttende linjeskift i beskeden, forkert hemmelighed eller nøgleformat (en Base64- eller hex-hemmelighed indtastet som Tekst eller omvendt) og forkert algoritme. Hex kontra Base64 er ikke et problem her: Sammenlign med accepterer hex med både store og små bogstaver, standard-Base64 og URL-sikker Base64.
Hvad er forskellen på HMAC og en almindelig hashværdi?
Er en HMAC det samme som en digital signatur?
Nej. Begge parter i en HMAC deler én hemmelighed, så alle, der kan verificere en HMAC-værdi, kan også oprette en. Signaturer som RSA eller ECDSA (RS256 eller ES256 i JWT'er) laves med en privat nøgle og kontrolleres med en offentlig nøgle. Derfor kan de, der verificerer dem, ikke forfalske dem.
Bliver min hemmelige nøgle sendt til en server?
Nej. HMAC-SHA1 og SHA-2-varianterne beregnes med browserens Web Crypto API og HMAC-MD5 med JavaScript på siden. Nøglen og beskeden forlader aldrig din enhed. Behandl alligevel hemmeligheder fra produktion med omhu, og udskift en nøgle, hvis den kan være blevet afsløret.