HMAC
Hash-based Message Authentication Code
- Pronunciation
- AYCH-mak
In short
HMAC combines a secret key with a hash function to produce a tag that proves a message came from someone who knows the key and wasn't changed on the way.
What is HMAC?
A plain hash such as SHA-256 detects accidental changes, but anyone can recompute it after tampering with a message. HMAC mixes a secret key into the hashing, in a carefully designed two-step construction, so only parties who share the key can produce or check a valid tag. It was published in 1996 and standardized in 1997.
It is everywhere in web development. Webhook providers such as Stripe and GitHub sign each request body with HMAC-SHA256 and a secret you share with them, so your server can reject forged events. JWTs signed with the HS256 algorithm use HMAC, cloud APIs such as AWS sign requests with it, and signed cookies use it to detect tampering.
Verifying a tag is simple: recompute the HMAC over the exact bytes received with the shared secret and compare. The comparison must be constant-time, using a function such as crypto.timingSafeEqual or hmac.compare_digest, because an ordinary string comparison stops at the first difference and can leak the correct tag through timing. Including a timestamp in the signed data prevents replaying old messages.
A common misconception is that HMAC encrypts the message. It doesn't hide anything; the message stays readable and the tag only proves integrity and authenticity. Because both sides share the same key, HMAC also can't prove to a third party which side sent a message, which is what digital signatures with public keys are for.
Key takeaways
- HMAC uses a secret key and a hash to make a tamper-proof tag.
- Only holders of the shared key can create or verify the tag.
- Webhooks, HS256 JWTs, API request signing and signed cookies use it.
- Compare tags in constant time and include timestamps against replays.
- It proves integrity, not secrecy, and isn't a public-key signature.
Example
import crypto from "node:crypto";
export function isValidWebhook(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody) // the exact bytes received, before JSON parsing
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader.replace(/^sha256=/, ""));
return a.length === b.length && crypto.timingSafeEqual(a, b); // constant-time compare
}Readers ask
What is the difference between HMAC and a hash?
A hash can be computed by anyone, so it only detects accidental changes. An HMAC also requires a secret key, so it proves the message came from someone who holds that key and wasn't altered.
What is the difference between HMAC and a digital signature?
HMAC uses one shared secret key on both sides. A digital signature uses a private key to sign and a public key to verify, so anyone can check it and only the key owner could have made it.
Why must HMAC comparison be constant-time?
A normal comparison returns as soon as it finds a mismatched character, so response times reveal how much of a guess was correct. Constant-time comparison takes the same time either way, closing that leak.
See also
- HashingSecurity, p. 14Hashing is the process of turning any input into a fixed-length value with a one-way function, used to verify data integrity and store passwords safely.
- WebhookBackend & APIs, p. 47A webhook is an automated HTTP request that one application sends to a URL you provide as soon as a specific event happens, such as a completed payment.
- JWTSecurity, p. 19A JWT is a compact, signed token that carries claims like a user ID and expiry time, letting a server verify requests without looking up a session.
- Digital SignatureSecurity, p. 11A digital signature is a cryptographic value made with a private key that proves who produced a message or file and that it hasn't changed since it was signed.
- API KeySecurity, p. 1An API key is a unique secret string that identifies an application or project when it calls an API, used to control access, track usage, and apply rate limits.
- EncryptionSecurity, p. 12Encryption is the process of scrambling data with a key so that only someone holding the correct key can turn it back into its original, readable form.
Spotted a mistake or something missing on this page?Suggest an edit