HMAC Generator
Keyed hashes for webhook signatures and API auth — computed locally with WebCrypto.
Paste the message (e.g. a raw webhook body), enter the secret key, pick the algorithm — the hex signature updates live.
HMAC Generator
Where you'll meet HMACs
- GitHub webhooks —
X-Hub-Signature-256: sha256=<hmac>is HMAC-SHA256 of the raw request body with your webhook secret. Paste body + secret above; the output should equal the part aftersha256=. - Stripe webhooks —
Stripe-Signaturesigns<timestamp>.<raw body>with your endpoint secret. Build that exact string as the message. - API request signing (AWS SigV4-style schemes) — chains of HMACs over canonical requests.
- JWTs (HS256) — the signature is HMAC-SHA256 over
base64url(header).base64url(payload)— decode them with the JWT decoder.
The #1 debugging gotcha: sign the byte-exact raw body. A single re-serialized space or reordered JSON key produces a different signature — never JSON.parse then re-stringify before verifying.
What's the difference between a hash and an HMAC?
A hash fingerprints data; an HMAC fingerprints data + a secret key. Anyone can recompute a hash, but only key-holders can produce the matching HMAC — that's what makes it an authentication code.
Is it safe to paste a webhook secret here?
The computation runs entirely in your browser via WebCrypto — the key and message are never sent anywhere. For production secrets, rotating after debugging is still good hygiene.
My computed signature doesn't match the provider's — why?
Almost always the message bytes: you signed pretty-printed JSON instead of the raw body, missed the timestamp prefix (Stripe), or compared against the header's prefix (strip 'sha256='). Algorithm and key come next.
Related tools
- Hash Generator — unkeyed digests (MD5/SHA).
- JWT Decoder — inspect the tokens HMACs sign.
- Checksum & Verify — file integrity end to end.
🔐 Private by design: this tool runs entirely in your browser — nothing is uploaded, stored or logged.