Tools · Hashing and verification
HMAC generator and checker
Compute or verify an HMAC with a text, hex or Base64 key. Checked against the RFC 4231 and RFC 2202 test vectors.
Nothing you type here leaves your browser. Even so, do not paste a production secret into any website; use a throwaway key to learn how it works.
This HMAC calculator computes an HMAC tag from a secret key and a message using SHA-256, SHA-512 and other hashes, and it can verify a tag you paste in. Anyone without the key can't produce a valid tag for a message of their choosing. Everything runs in your browser. Please use a throwaway key to learn with, not a production secret.
What an HMAC is
An HMAC (hash-based message authentication code) is a short tag computed from a message and a secret key. You send the message and the tag. The receiver, who shares the key, recomputes the tag and compares. If they agree, the message came from someone who knows the key and wasn't changed on the way. A webhook signature (Stripe's, GitHub's, Slack's), the signature on a JSON Web Token marked HS256 and a signed cookie are all HMACs.
RFC 2104 and FIPS 198-1 define the construction:
HMAC(K, m) = H( (K' ⊕ opad) ‖ H( (K' ⊕ ipad) ‖ m ) )Here H is the hash (SHA-256, say), K' is the key padded with zero bytes to the hash's block size (64 bytes for SHA-1 and SHA-256, 128 for SHA-384 and SHA-512, and a longer key is hashed first), and ipad and opad are the bytes 0x36 and 0x5c repeated. Two nested hashes with the key mixed in at both layers is what makes it safe. The tool above runs that exact construction from the vetted @noble/hashes library, and the test suite checks it against the RFC 4231 and RFC 2202 vectors, which you can load with the buttons.
Why not just hash the key and the message together?
Because the obvious SHA-256(key ‖ message) has a flaw. SHA-256, SHA-1, SHA-512 and MD5 feed the input through a fixed-size state a block at a time, and their digest is that state at the end. Anyone who sees H(key ‖ m) can carry on from it and compute H(key ‖ m ‖ padding ‖ extra) without knowing the key. That's a length extension attack. HMAC's second, outer hash seals the state. It's why HMAC is safe for authentication even with MD5 or SHA-1, and why the SHA-3 family, which doesn't have the problem, can use a simpler keyed construction (KMAC). The HMAC article works through an actual extension attack on a SHA-256 tag, step by step.
Using it in code
// Node
const { createHmac, timingSafeEqual } = require('crypto');
const tag = createHmac('sha256', key).update(message).digest();
if (!timingSafeEqual(tag, received)) throw new Error('bad tag');
// Browser
const k = await crypto.subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
const ok = await crypto.subtle.verify('HMAC', k, receivedTag, messageBytes);An HMAC authenticates but doesn't hide the message. AES-GCM does both at once, with its tag playing the role of the HMAC. Always verify with the library's verify function or a constant-time comparison, never == on strings, and always compute the tag over the exact bytes you received, before parsing them. The tool's verify box is for checking by hand. It compares in constant time too, though a web page isn't the place to defend against timing attacks.
Which algorithm?
HMAC-SHA256 is the sensible default, and almost every API uses it. HMAC-SHA512 and HMAC-SHA384 give longer tags and are no worse. HMAC-SHA1 and HMAC-MD5 are still considered safe as MACs, because the known collision attacks on those hashes don't break HMAC, but new designs shouldn't choose them. A tag is only as strong as its key, so use at least as many random bytes as the hash's output (32 for SHA-256), generated with a proper random source and not a word. The plain hash tool computes the unkeyed hashes. Inside cipher.ink, HMAC-SHA256 is the pseudo-random function in PBKDF2, which stretches a passphrase into an encryption key (see the PBKDF2 benchmark).
Common questions
Is an HMAC the same as a signature?
No. An HMAC uses one shared secret, so anyone who can verify a tag can also create one. A digital signature (RSA, ECDSA, Ed25519) has a private key to sign and a public key to verify, so the verifier can't forge.
Does an HMAC encrypt the message?
No. The message stays readable, and the tag only proves who made it and that it wasn't altered. To hide the message, encrypt it, preferably with an authenticated mode such as AES-GCM, which does both jobs in one.
What if my key is longer than the block size?
HMAC hashes it first and uses the digest as the key. A key shorter than the block is padded with zeros. Either way the result is deterministic and matches every standard implementation.
My tag doesn't match the other system's.
Check three things: the key's encoding (a hex string isn't the same key as its text), the exact bytes of the message (trailing newline, character encoding), and the algorithm. The two test-case buttons are a quick sanity check of the tool itself.