{{ summaryTitle }}
{{ summaryArtifact }}

{{ summaryLine }}

Algorithm {{ resultsReady ? algorithmLabel : '—' }} Verification {{ verificationLabel }}

{{ copyAnnouncement }}

HMAC signing inputs
Message content stays in this browser tab and is never added to the share URL.
{{ messageSourceHint }}
The selected format changes the bytes authenticated by HMAC.
Use the representation documented by the signing provider.
The secret is held only in local page state and is excluded from URLs and exports.
{{ secretActionHint }}
Algorithm choice changes digest bytes, output length, prefix, chart, and verification.
Formatting does not change the underlying HMAC bytes.
Algorithm prefix emits values such as sha256=.
Limited to 40 characters and applied exactly as typed.
Auto resolves from the stripped value and selected digest length; use an explicit format when the source is ambiguous.
Optional. Verification compares decoded bytes instead of display text.
Exact text leaves message bytes unchanged.
This display-only choice is not shareable and does not change the digest.
{{ showSecret ? 'Visible' : 'Hidden' }}
{{ signatureArtifactText }}

{{ signatureExportStatus }}

{{ chartExportStatus }}

The chart renderer is unavailable. Digest-size values remain available in the signing ledger.

SignalValueMeaningCopy
{{ row.label }}{{ row.display }}{{ row.detail }}

{{ ledgerExportStatus }}

Introduction:

Webhook verification often fails even when the visible JSON looks unchanged. HMAC authenticates bytes, so a final newline, different character encoding, decoded secret, or altered property spacing is enough to produce a completely different result. The receiver must repeat the sender's exact signing recipe.

A hash-based message authentication code combines a message with a shared secret and a cryptographic hash function. Both parties can generate the same fixed-length tag when they have the same bytes and key. A matching tag supports two conclusions: the signed bytes were not altered after signing, and the signer knew the shared secret.

Message bytes
The exact body, canonical string, or decoded byte sequence being authenticated.
Key bytes
The shared secret after its chosen UTF-8, hexadecimal, Base64, or Base64URL interpretation.
Digest
The raw authentication tag, later represented as hexadecimal, Base64, or Base64URL text.
Header value
An optional provider prefix such as sha256= or v1= followed by the formatted digest.

HMAC is not encryption. It does not hide the message, and anyone who has the shared secret can create a valid tag. It also differs from a plain hash because an attacker who only knows the message cannot reproduce the HMAC without the key. Unlike a public-key signature, HMAC does not identify which of the secret holders created the tag.

The displayed format comes after the cryptographic calculation. Lowercase hex, uppercase hex, Base64, and Base64URL can all represent the same digest bytes. Prefix text is also outside the HMAC formula. Changing either presentation choice will alter the copied string while leaving the underlying tag unchanged.

A match should be treated as one check in a wider verification process. Production webhook handlers commonly verify a timestamp or replay window, preserve the raw request body, select the correct secret, and reject mismatches before parsing or acting on the message.

How to Use This Tool:

Match the sender's byte recipe before comparing the visible signature string.

  1. Enter the exact message or load a local text file up to 512 KB. Choose whether its contents are UTF-8 text, hexadecimal bytes, Base64, or Base64URL.
  2. Enter the shared secret and select its real representation. A Base64-looking secret must remain UTF-8 text when the provider documents it as literal text.
  3. Choose the required HMAC algorithm and message treatment. Newline trimming and CRLF-to-LF conversion apply only to UTF-8 text; byte-encoded messages remain exact.
  4. Select the digest output and header prefix. These choices format the tag but do not change its bytes.
  5. Paste an expected signature when available. If the result differs, compare message bytes, key bytes, algorithm, and newline handling before changing the output format.

Interpreting Results:

Match means the decoded expected value and generated tag contain the same bytes. Mismatch means they differ; it does not identify which input was wrong. Parse error means the expected text could not be decoded in the selected or detected format.

The byte counts are useful diagnostics. An unexpected message length often reveals newline or encoding changes, while an unexpected key length suggests that text was decoded when it should have remained literal, or vice versa. Check the raw digest when a prefixed header differs, because the prefix itself is not authenticated.

Do not infer confidentiality, freshness, authorization, or protection against replay from a matching HMAC. Those properties need separate protocol rules.

Technical Details:

RFC 2104 defines HMAC as a nested hash over a block-sized key. Keys longer than the hash block are first hashed; shorter keys are padded with zero bytes. Two fixed pads separate the inner message hash from the outer authentication hash.

Formula Core:

The canonical construction is:

HMAC(K,m) = H( (K′⊕opad) ‖ H((K′⊕ipad)‖m) )

H is the selected SHA hash, K′ is the normalized block-sized key, m is the message byte sequence, ipad repeats byte 0x36, opad repeats byte 0x5c, and || means byte concatenation. No numeric rounding occurs.

Transformation Core:

HMAC byte transformation and verification stages
Stage Transformation Failure clue
Decode inputs Interpret message and key as UTF-8, hex, Base64, or Base64URL bytes. Invalid alphabet, odd-length hex, empty decoded key, or unexpected byte count.
Treat message Keep exact UTF-8 text, remove one final newline, or replace CRLF pairs with LF. Encoded-byte modes remain exact. A visually identical body produces a different message length.
Normalize key Hash a key longer than the selected block, then zero-pad it to 64 or 128 bytes. The secret representation was chosen incorrectly.
Calculate tag Apply the nested HMAC construction with the chosen SHA family. Algorithm or signed bytes differ from the sender.
Format and compare Encode the raw tag, add a display prefix, strip common prefixes from the expected value, decode it, and compare bytes. Raw digest matches but header text does not, or expected-format detection was ambiguous.
Supported HMAC hash profiles
Algorithm Digest Hash block Use note
HMAC-SHA-1160 bits64 bytesLegacy compatibility only
HMAC-SHA-224224 bits64 bytesCompatibility option
HMAC-SHA-256256 bits64 bytesDefault choice
HMAC-SHA-384384 bits128 bytesLonger SHA-2 tag
HMAC-SHA-512512 bits128 bytesLongest supported tag

Automatic expected-format detection treats exact-length hexadecimal text as hex, text containing - or _ as Base64URL, and other accepted text as Base64. Select an explicit expected format when a value could be read more than one way.

Privacy and Safety Notes:

Messages, loaded files, expected signatures, and secret keys are processed in the browser. The secret is excluded from the share URL and result exports. Use only test secrets on a browser page; production secrets should remain in a vault or server-side verifier where access, rotation, logging, and replay controls can be enforced.

The local test-key action creates 32 random bytes and represents them as Base64URL. It is useful for examples, but revealing the value on screen or copying it into unmanaged notes still exposes the secret.

Worked Examples:

RFC test vector

Using UTF-8 message what do ya want for nothing?, UTF-8 key Jefe, HMAC-SHA-256, and lowercase hexadecimal output produces 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843. An expected value beginning with sha256= matches after the prefix is stripped and the hex bytes are decoded.

References: