HMAC Generator
Generate and verify HMAC signatures with SHA-256, SHA-384, SHA-512 or SHA-1, with the reason a plain hash of key and message is not equivalent.
Verify a signature
Two different keys can produce the same signature
HMAC needs a key exactly one block long, and it gets one whatever you type. SHA-1 and SHA-256 work in 64-byte blocks; SHA-384 and SHA-512 in 128-byte blocks. A key longer than the block is replaced by its own digest. A key shorter than the block is padded out with zero bytes. Neither is an error and neither is reported.
| Hash | Block | Digest | One byte under | Exactly a block | One byte over |
|---|---|---|---|---|---|
| SHA-1 | 64 B | 20 B | padded | used as is | hashed |
| SHA-256 | 64 B | 32 B | padded | used as is | hashed |
| SHA-384 | 128 B | 48 B | padded | used as is | hashed |
| SHA-512 | 128 B | 64 B | padded | used as is | hashed |
So a 65-byte key and the raw bytes of its own SHA-256 digest are the same key to HMAC-SHA-256 — feed either one in and the signature is identical. The threshold is strict: 64 bytes is used as it is, 65 is hashed, and there is nothing in between. The padding end is the one that bites in practice. "key" and "key" followed by sixty-one NUL bytes sign identically, so a key that passes through a fixed-width column or a null-terminated string will still verify — silently, and with the wrong secret.
The dropdown changes what your key is, not just the output
Because the block size depends on the hash, the same secret can be treated two different ways depending on which option is selected above. A 100-byte key:
| Hash | Block | What happens to a 100-byte key |
|---|---|---|
| SHA-1 | 64 B | hashed down to its digest |
| SHA-256 | 64 B | hashed down to its digest |
| SHA-384 | 128 B | kept, padded to the block |
| SHA-512 | 128 B | kept, padded to the block |
The 64-byte hashes collapse it; the 128-byte ones keep every byte. That applies to any key from 65 to 128 bytes — 64 different key lengths where switching the dropdown changes whether your secret survives intact. At exactly 64 bytes the two read differently — used as is against padded — but both keep every byte, so nothing is lost either way. The line worth watching is hashed or not. SHA-384 shares SHA-512's block because it is SHA-512 truncated, which is also why its block is larger than its digest — as every row above is.
On output length, and the comparison that has to be done properly
The signature is as long as the digest and nothing else — a one-byte key and a two-hundred-byte key both give 64 hex characters from SHA-256. Base64 packs the same bytes into 44 characters, 31% shorter, which is why tokens and headers tend to use it. And if something asks for 256 bits, do not hand it the first half of a SHA-512 signature: that is not an HMAC-SHA-256, it is an unrelated value that happens to be the right length.
An ordinary === stops at the first character that differs. In a browser,
checking a value you just computed yourself, there is nobody to time it and it would not
matter — but the verifier above does not do that anyway, because a page explaining the
technique ought to use it. It accumulates the difference across every character with XOR
and checks the total at the end, so the work does not depend on where the mismatch is.
On a server checking a signature someone else supplied, the shortcut turns a
64-character search into roughly
1,024 guesses — sixteen options per position,
one position at a time. That is the entire reason constant-time comparison exists, and
comparing lengths first is not a leak worth avoiding — the length of a signature is
public, and every real implementation gives it away too.
How to use
- Enter your message and secret key.
- Choose a hash algorithm.
- Read the signature.
- Verify by comparing against an expected value.
Frequently asked questions
What is an HMAC for?
Proving that a message came from someone holding the shared secret and has not been altered in transit. It is used for webhook signatures, API request signing and session tokens — anywhere the receiver needs to trust the sender without encrypting the content.
Why not just hash the key and message together?
Because the naive construction is vulnerable to length-extension attacks against hashes built the way SHA-1 and SHA-256 are. An attacker can append data and produce a valid-looking result without knowing the key. HMAC's nested double-hashing structure exists precisely to prevent this, and it is not an arbitrary complication.
Is HMAC-SHA1 still acceptable?
Yes, unusually. HMAC's security does not rest on collision resistance, so the SHA-1 collision attacks do not break it, and HMAC-SHA1 is still considered sound. Even so, SHA-256 is the sensible default for anything new.
How should signatures be compared?
With a constant-time comparison. An ordinary string comparison returns as soon as it finds a mismatched byte, and the timing difference leaks how much of the signature was correct — enough for an attacker to reconstruct it byte by byte. Every crypto library provides a timing-safe comparison for this reason.
What is the difference from a digital signature?
HMAC uses one shared secret, so anyone who can verify can also forge. A digital signature uses a private key to sign and a public key to verify, so verification does not confer the ability to sign. That distinction is what makes signatures suitable for non-repudiation and HMAC not.
Does my key get transmitted?
No. Everything is computed in your browser through the Web Crypto API and nothing is sent anywhere, which matters given that the input is by definition a secret.
🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.