HMAC generator for signing and verifying messages
HMAC (hash-based message authentication code, RFC 2104) combines a secret key with a hash function to produce a tag that proves a message came from someone who knows the key and was not changed on the way. This HMAC generator computes HMACs with nine hash functions, text, hex or Base64 keys, and hex or Base64 output — exactly what you need to debug webhook signatures or API request signing.
Example
Message The quick brown fox jumps over the lazy dog, key key, HMAC-SHA256:
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8The same HMAC in Base64 is 97yD9DBThCSxMpjmqm+xQ+9NWaFJRhdZl0edvC0aPNg=. Many APIs send signatures in Base64, others in hex — the value is the same, only the encoding differs.
How HMAC works
HMAC hashes the message twice with two keys derived from your secret: HMAC(K, m) = H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ m)). Keys longer than the hash block size are hashed first; shorter keys are padded with zeros. This nested construction is what makes HMAC safe even with hash functions like SHA-256 that are vulnerable to length-extension attacks when used naïvely as H(key + message).
HMAC vs a plain hash
| Hash (e.g. SHA-256) | HMAC | |
|---|---|---|
| Needs a key | No | Yes |
| Anyone can compute it | Yes | Only key holders |
| Proves integrity against attackers | No — an attacker can recompute it | Yes |
| Proves who sent it | No | Yes, among parties sharing the key |
Where you will use HMAC
- Webhooks. GitHub sends
X-Hub-Signature-256: sha256=<hex HMAC>of the raw request body; Stripe, Shopify and Slack use HMAC-SHA256 schemes with their own header formats and, often, a timestamp included in the signed data. - API request signing, such as AWS Signature Version 4, which chains several HMAC-SHA256 operations.
- JSON Web Tokens with the HS256, HS384 or HS512 algorithms — see the JWT Decoder.
- One-time passwords: TOTP and HOTP are built on HMAC-SHA1 by default.
Debugging signature mismatches
- Sign the exact raw bytes the sender signed. Re-serialising parsed JSON changes whitespace and key order and breaks the signature.
- Use the right key format: many providers show secrets as hex or Base64 — choose the matching Key format instead of pasting them as text.
- Match the output encoding and any prefix (such as “sha256=”).
- Check whether the provider signs extra data, such as a timestamp joined to the body.
In application code, compare signatures with a constant-time function (for example crypto.timingSafeEqual or hmac.compare_digest) to avoid timing attacks.
Choosing the hash
HMAC-SHA256 is the standard choice. HMAC-SHA512 and HMAC-SHA3 are fine alternatives. HMAC-MD5 and HMAC-SHA1 are not broken as MACs in the way MD5 and SHA-1 are as hashes, but they are legacy options — use them only for compatibility. The HMAC is computed in your browser, and the key and message are not sent anywhere while you work. A Save & Share link is different: it stores the message and the form settings, including the secret key, on our server, so clear the key first if it is a real one — and avoid pasting production secrets into any website. For unkeyed hashes, see the SHA-256 Hash Generator.