HMAC generator
Compute a keyed HMAC over a message using SHA-1, SHA-256, SHA-384, or SHA-512.
What this does
HMAC-SHA512 generates a 512-bit message authentication code from a message and a secret key. Unlike a plain SHA-512 hash, only someone with the shared key can reproduce the tag. Choose SHA-512 in this tool when a protocol or existing integration specifically requires it. Use the algorithm required by your protocol or integration.
This tool also computes HMAC-SHA1, HMAC-SHA256, and HMAC-SHA384 with the browser's SubtleCrypto. The key can be entered as UTF-8 text, hex, or Base64, and the tag can be shown as hex or Base64, so you can reproduce whatever format the system you're integrating with uses.
HMAC is defined by RFC 2104; the SHA-512 hash function is specified in NIST FIPS 180-4.
Everything runs locally. Nothing about the key or message is transmitted.
When you'd use it
- Verifying an incoming webhook signature (Stripe, GitHub, Shopify, Slack, and many others sign their payloads with HMAC-SHA256).
- Signing an outgoing API request that uses a shared-secret scheme (for example AWS SigV4-style or older HMAC auth).
- Generating a tamper-evident token or a signed URL parameter.
- Debugging a signature mismatch by isolating which input — body, key encoding, output encoding — is wrong.
Worked example
Message id=42&amount=1000, key topsecret (as
UTF-8 text), HMAC-SHA256, hex output:
641bedff29f7168bc87504b5927bf20598fcf9cd5a4f5022b8317310f0de54a9
Switch the output to Base64 and the same 32 bytes become
ZBvt/yn3FovIdQS1knvyBZj8+c1aT1AiuDFzEPDeVKk= — this is exactly
the choice that trips people up when a provider's header is Base64 but
their example code prints hex. Change the
key encoding to "Hex" without changing the key text and the tool rejects it:
after non-hex characters are removed, an odd number of digits remains.
Reproduce the provider's documented
example first; once that matches, your real payload will too.
Limits and gotchas
- Sign the exact bytes. For webhooks, that usually means the raw request body before any JSON parsing or reformatting.
- Key encoding is not cosmetic. The same characters interpreted as text, hex, or Base64 are three different keys.
- Output encoding must match the value you compare against, including any provider prefix like
sha256=. - Production comparisons must be constant-time. Don't ship a plain
===check. - HMAC-SHA1 is still cryptographically acceptable for HMAC use, but choose SHA-256 for anything new unless a spec forces SHA-1.
- This is authentication, not encryption. The message is not hidden; HMAC only detects tampering and proves origin.
Frequently asked questions
- What is the difference between a hash and an HMAC?
- A plain hash of
messagecan be recomputed by anyone. An HMAC mixes a secret key into the hashing process, so only someone who holds the key can produce or check the value. That is what makes it a message authentication code: it proves both that the message wasn't altered and that it came from someone with the key. - My HMAC doesn't match the webhook's signature header.
- The usual causes: (1) hashing the wrong bytes — many providers sign the exact raw request body, so re-serialising the JSON changes it; (2) wrong key encoding — the secret might be hex or Base64, not text; (3) the provider prefixes the value (for example
sha256=) or uses Base64 while you used hex; (4) a timestamp or other field is concatenated with the body before signing. Check the provider's signing recipe precisely. - Why can't I just use == to compare two HMACs in my own code?
- A normal string comparison returns as soon as it finds a differing byte, which leaks timing information an attacker can use to recover the correct value byte by byte. Use a constant-time comparison function (
crypto.timingSafeEqualin Node,hmac.compare_digestin Python). Comparing here in the browser for debugging is fine; the production check needs to be constant-time. - Is the secret I type sent anywhere?
- No. The key and message are passed to the browser's SubtleCrypto HMAC implementation locally. Nothing leaves the page. Still, prefer a test key over your real production secret when you can.