HMAC Generator: Message Authentication, Not Just Hashing
A plain hash proves a message hasn't been tampered with, but anyone can compute a plain hash — it doesn't prove who sent it. HMAC (Hash-based Message Authentication Code) fixes this by mixing a shared secret key into the hash, so only someone who knows the key could have produced a matching digest. This tool computes HMAC using the browser's native, standards-compliant Web Crypto implementation.
H is the underlying hash function (SHA-1/256/384/512); K' is the key, padded/hashed to the block size.
Why HMAC Instead of Hash(secret + message)
Naively concatenating a secret and a message before hashing has known vulnerabilities (length-extension attacks against certain hash constructions). HMAC's specific double-hashing structure with inner and outer padding is a well-analyzed construction proven secure as long as the underlying hash function is, which is why it's the standard approach rather than ad-hoc concatenation.
Where HMAC Shows Up in Practice
Webhook providers (Stripe, GitHub, Shopify) sign payloads with HMAC so receivers can verify a request genuinely came from them and wasn't forged or tampered with in transit. JWT's HS256 algorithm is literally HMAC-SHA256 applied to the token's header and payload. AWS's request signing (SigV4) and many other API authentication schemes are also HMAC-based.
Verifying a Webhook Signature Manually
When debugging a signature mismatch, compute the HMAC of the exact raw request body (not a re-serialized or reformatted version — even whitespace differences change the result) using the shared secret, then compare it to the signature the sender included in a header. A mismatch almost always means the body was altered somewhere in transit or reformatting, not that the secret is wrong.
Practical Examples
Verifying a Stripe-Style Webhook
Confirming payload authenticity.
- 1.Message: raw webhook request body
- 2.Secret: your webhook signing secret
- 3.Compare computed HMAC to the X-Signature header
Understanding a JWT's Signature
HS256 is HMAC-SHA256 under the hood.
- 1.Message: base64url(header) + '.' + base64url(payload)
- 2.Secret: the JWT signing secret
- 3.Result matches the JWT's third segment (base64url-encoded)
Algorithms Supported
- HMAC-SHA1: legacy compatibility
- HMAC-SHA256: the modern standard default
- HMAC-SHA384 and HMAC-SHA512: larger output for extra margin
Good Use Cases
- Debugging a webhook signature verification failure
- Understanding how a JWT's HS256 signature is computed
- Generating a signature for a custom API authentication scheme
- Learning the difference between hashing and message authentication
Frequently Asked Questions
What's the difference between a plain hash and an HMAC?
A plain hash (like SHA-256) takes only a message. An HMAC additionally requires a secret key, producing a value that only someone who knows the key could have generated — this is what makes HMAC useful for verifying both integrity and authenticity, not just integrity.
What is HMAC commonly used for?
Signing webhook payloads (so the receiver can verify a request actually came from the expected sender), API request signing (like AWS Signature V4), JWT HS256 signatures, and message integrity checks in general where both parties share a secret.
Which hash algorithm should I use?
SHA-256 is the standard modern default — strong and fast. SHA-1 is still used by some legacy systems (like older webhook implementations) but is considered weak for other cryptographic purposes; use it only for compatibility with a system that specifically requires it. SHA-384/512 offer a larger output for applications wanting extra margin.
Why does the output change completely if I change one character in the message?
This is the avalanche effect, a core property of cryptographic hash functions — even a tiny change in input should produce a completely different, unpredictable output. It's what makes HMAC useful for detecting any tampering with the message.
Can I use this to verify an incoming webhook signature?
Yes — paste the exact raw request body as the message and the webhook secret as the key, then compare the resulting HMAC to the signature header the webhook sender included. The comparison should happen in constant time server-side in production, but this is useful for manually debugging a signature mismatch.
Is my secret key sent anywhere?
No, HMAC computation happens entirely in your browser using the Web Crypto API — nothing is transmitted.