Skip to content
ToolBoxGeniehome

HMAC Generator

Developer Tools · Added

A plain hash proves a message has not changed. An HMAC proves it came from somebody holding the key — which is why webhook providers sign with one. Paste the message and the key, pick the hash, and compare the result against what arrived.

The exact bytes that were signed. A reformatted JSON body will not match.

Use a test key. See the note below the result.

The default nearly everywhere, and what Stripe, GitHub and most webhook providers sign with.

Compared without short-circuiting — see the note about timing below.

Try:

How to use the hmac generator

  1. 1Paste the exact message that was signed, byte for byte, into the message box.
  2. 2Enter the secret key and say how it is written: plain text, hex or Base64.
  3. 3Pick the hash algorithm the sender used — SHA-256 unless their docs say otherwise.
  4. 4Read the digest as hex, Base64 or Base64url, or paste the expected value in to compare.

Examples

A short message with a text key

Input
Message "The quick brown fox", key "secret", SHA-256
Result
7a284e5025f32a846fa3e6957d10278eb5726dd4e0b04c8e0259defcd2cd0eb1

Flagged with a warning: a 6-byte key is well short of the 32 bytes RFC 2104 recommends for SHA-256.

Checking a webhook signature

Input
The raw request body, the shared secret as Base64, SHA-256, output as Base64
Result
A digest to set against the provider's signature header. A mismatch usually means the body was re-serialised before it reached you.

About the hmac generator

Why HMAC is not just hash(key + message)

The obvious construction — concatenate the key and the message, then hash — is broken against the hash functions people actually use. SHA-1 and the SHA-2 family are built on the Merkle-Damgård construction, which lets somebody who knows a digest and the message length append data and compute a valid digest for the longer message, with no knowledge of the key at all. It is called a length-extension attack and it is entirely practical.

HMAC exists specifically to close that hole. It hashes twice with two different key-derived pads, so the final digest is a hash of a hash and the internal state an attacker would need to extend is never exposed. That structure is why the standard is a standard rather than a note saying 'stick the key on the front'.

Key length, and what the standard actually asks for

RFC 2104 recommends a key at least as long as the hash output — 32 bytes for SHA-256 — because the security of the construction is capped by the key's own length. A four-character password used as an HMAC key is guessable regardless of how strong the underlying hash is, and this page says so when you use one.

The other end has a limit too. A key longer than the hash's block size, 64 bytes for SHA-256, gets hashed down to the output length before use, so extra bytes beyond that add nothing at all. Somewhere between the output length and the block size is the whole useful range.

Frequently asked questions

How does an HMAC differ from a plain hash?
A plain hash is a public function: anybody can alter a message and recompute its digest, so on its own it proves nothing about origin. HMAC folds a secret key into the hashing in two passes, so only a holder of the key can produce a digest that verifies. That is authentication as well as integrity, and it is the reason webhooks sign rather than merely hash.
My signature does not match. What is usually wrong?
Almost always the message rather than the key. Signatures are computed over exact bytes, so parsing JSON and re-serialising it, normalising line endings from LF to CRLF, or losing a trailing newline will each break the match while leaving the payload looking identical. Capture the raw body before anything touches it and sign that.
Where does the computation happen?
Entirely in your browser, through the Web Crypto API the platform already ships. No key, message or digest is sent anywhere, and there is no request to make one in. Web Crypto needs a secure context to exist at all, so on a page served over plain HTTP the tool reports that rather than falling back to something weaker.
Should I still use SHA-1 here?
Only when something you do not control demands it. SHA-1's collision resistance is broken, but HMAC does not lean on collision resistance, so HMAC-SHA-1 is not considered broken and TOTP still uses it. That is a reason not to panic about existing systems, not a reason to pick it for anything new — start at SHA-256.
Why does comparing here not have the timing problem I have read about?
The comparison on this page checks every character rather than stopping at the first difference, so it takes the same time whichever way it comes out. That habit matters on a server, where an attacker can measure thousands of responses and learn a signature one byte at a time. In a browser tab there is nobody to measure it, but writing it the other way would still be teaching the wrong pattern.