Skip to content

HMAC Calculator

Options

HMAC-SHA256 signature

Estimates for educational purposes — not financial, medical, or legal advice. See terms.

HMAC (Hash-based Message Authentication Code) is the standard way to sign data with a shared secret. Give it a key, a message, and a hash function, and it produces a signature that can only be computed by someone who knows the key. The recipient can verify the signature — proving both that the message was generated by a party who knew the key, and that the message hasn’t been modified in transit. HMAC is used everywhere: API request signing (AWS, Stripe, Shopify), webhook validation (GitHub, Slack, Twilio), JWT tokens with HS256, and countless custom authentication schemes.

This tool computes HMAC signatures for any message and key using the browser’s Web Crypto API, with support for SHA-1, SHA-256, SHA-384, and SHA-512 as the underlying hash function. Type a key and a message, pick an algorithm, and the hex-encoded signature appears. Everything runs in your browser — the key and message never leave your device.

How HMAC works

HMAC is a specific construction on top of any hash function. Given a key $K$, a message $M$, and a hash function $H$:

HMAC(K,M)=H(KopadH(KipadM))\text{HMAC}(K, M) = H\big(K_{\text{opad}} \mathbin{\|} H(K_{\text{ipad}} \mathbin{\|} M)\big)

Where $K_{\text{ipad}}$ and $K_{\text{opad}}$ are the key XORed with two fixed byte patterns (0x36 and 0x5c, each repeated to fill the hash’s block size), and $|$ is concatenation.

The two-layer structure exists to defeat the length-extension attack that affects naive hash-based signatures. If you just compute $H(K | M)$, an attacker who sees that hash and knows the length of $K$ can compute $H(K | M | X)$ for arbitrary $X$ without knowing $K$, because of how Merkle-Damgård hash functions (SHA-1, SHA-256, SHA-512) construct their internal state. The inner hash in HMAC blocks this: even if an attacker knows the inner hash output, they can’t extend it and then run it through the outer hash without knowing the key.

You don’t need to understand the math to use HMAC — the Web Crypto API takes care of it. But knowing why HMAC exists instead of just SHA-256 saves you from reinventing a broken scheme.

Example: AWS-style request signing

AWS S3’s older V2 signing scheme used HMAC-SHA1. You’d construct a canonical string-to-sign from the request method, headers, and path, then compute HMAC-SHA1 with your AWS secret access key, base64-encode the result, and include it as the Signature parameter. The server would do the same computation server-side — if the two signatures matched, the request was authenticated.

V4 (current) uses HMAC-SHA256 in a more elaborate multi-step derivation to produce a per-request signing key, but the primitive is still HMAC. Most cloud APIs use some variant of this scheme: HMAC a canonical representation of the request with a shared secret to produce a signature that can’t be forged without the secret.

Example: GitHub webhooks

When GitHub sends you a webhook, it includes an X-Hub-Signature-256 header that is sha256= followed by the HMAC-SHA256 of the request body, using a secret you configured on the webhook. You verify by computing HMAC-SHA256(your_secret, request_body) and comparing it (constant-time) to the header value. If they match, the webhook is authentic. If they don’t, either the payload has been tampered with or someone’s trying to forge events.

Example: JWT with HS256

A JSON Web Token with HS256 is structured as base64url(header) + "." + base64url(payload) + "." + signature, where the signature is HMAC-SHA256 of the first two parts joined with a dot, keyed with a shared secret. The receiver validates by recomputing the HMAC over the same concatenation and comparing it to the provided signature. HS256 tokens are cheap to generate and verify but require both parties to share the secret — if you need asymmetric key signing, use RS256 or ES256 instead.

What this tool does not do

It does not support HMAC-MD5 because browser Web Crypto doesn’t — MD5 is deprecated for collision resistance, and shipping it would require bundling a pure-JS MD5 implementation which would add weight for a deprecated algorithm. For new work, use HMAC-SHA256 at a minimum. Legacy systems that still require HMAC-MD5 need a dedicated library.

It does not handle hex-encoded keys automatically — if your API uses hex keys, you’d need to decode them to raw bytes first, which this tool doesn’t offer in the UI. Both key and message are treated as UTF-8 strings. If you need to sign with a binary key, use the underlying computeHmac() function from a script or a more flexible tool.

It does not implement key stretching (PBKDF2, HKDF) — those are separate primitives for deriving a signing key from a password or a master secret. HMAC is the signing step after you already have a proper key. For unauthenticated hashing (no secret key), the hash generator produces the raw digest of the same SHA family.

Frequently asked questions

What is HMAC and why do I need a key?

HMAC stands for Hash-based Message Authentication Code. It's a way to prove that a message was generated by someone who knew a shared secret key — that way a recipient who also knows the key can verify the message is authentic and hasn't been altered. Unlike a plain hash (SHA-256 of the message), an HMAC includes the key in the computation, so you can't recompute it without the key. This is why it's used for API signing, webhook authentication, and JWT with HS256 — the server signs a payload with its secret, sends the payload plus signature to the client, and the client (or a proxy) can verify the signature without being able to forge new ones.

Why HMAC-SHA256 specifically and not just SHA-256?

Because plain SHA-256 has a length-extension vulnerability: if someone has a hash of message X and knows the length of X but not X itself, they can compute the hash of X plus arbitrary additional data. HMAC wraps the hash function in a two-layer construction with the key that prevents this attack. So a naive 'signature' like SHA-256(key + message) is insecure, but HMAC-SHA256(key, message) is secure. Use HMAC whenever you're 'signing' with a shared secret; don't roll your own by hashing a concatenation.

Is HMAC-MD5 supported?

No. MD5 has been broken for collision resistance for years and is deprecated; browser Web Crypto deliberately does not ship MD5 as a supported hash. If you have a legacy system that uses HMAC-MD5, you'll need a dedicated library that bundles its own MD5 implementation, not a tool that relies on the browser's native crypto. For anything new, use HMAC-SHA256 at a minimum.

Why is the signature different when my key or message changes by one character?

Because HMAC, like any good cryptographic hash, is designed so that any change — even a single bit — produces a completely different output. This is the avalanche effect, and it's what makes HMAC useful for integrity: even the tiniest accidental or deliberate modification of the message produces a signature that doesn't match the expected value. If you're debugging HMAC interop with another system and your signatures don't match, the cause is almost always subtle differences in how the message or key is encoded — trailing whitespace, different line endings, differences in JSON serialization, character encoding mismatches.

What encoding does the tool use for the message and key?

UTF-8. Both the key and the message are encoded as UTF-8 bytes before being fed to the HMAC algorithm. This matches how most APIs work — but be careful when interoperating with systems that use other encodings. If the other side encodes as ASCII, UTF-8 will match as long as the input is pure ASCII. If it encodes as Latin-1 or UTF-16, the bytes will differ and your signatures won't match. When in doubt, check the API documentation for which encoding it expects.