What Is HMAC? Message Authentication Explained
HMAC combines a secret key with a hash function to prove a message wasn't altered and came from someone who holds the key. Here's how it works.
HMAC, or Hash-based Message Authentication Code, combines a cryptographic hash function with a secret key to produce a short tag that proves two things at once: the message hasn’t been altered in transit, and whoever produced the tag knows the secret key. It’s one of the most widely deployed pieces of applied cryptography on the internet, sitting quietly behind webhook signatures, API request signing, and one of the two standard JWT signing algorithms.
Why a plain hash isn’t enough
A hash function alone — see hashing vs encryption for the distinction between the two — proves that data matches a known fingerprint, but it proves nothing about who produced that fingerprint. Anyone can compute SHA-256(message) and attach it to a tampered message; the hash of the tampered version will simply be a different, equally valid-looking fingerprint. Without a secret involved somewhere, a hash alone can’t distinguish a legitimate sender from an attacker who intercepted and modified the message.
The naive fix — hashing the secret key concatenated with the message, hash(key + message) — turns out to be vulnerable to a length-extension attack against certain hash constructions: an attacker who doesn’t know the key can still compute a valid tag for a longer message by appending data to a known valid message-and-tag pair. HMAC exists specifically to close that gap.
How HMAC actually works
HMAC runs the hash function twice, with the key mixed in through two different padding constants (conventionally called the inner and outer pad) rather than simply prepended once:
HMAC(key, message) = H( (key XOR opad) + H( (key XOR ipad) + message ) )
You never need to implement this by hand — every mainstream cryptography library exposes an hmac function that takes a key, a message, and a hash algorithm (commonly SHA-256) and returns the tag. The nested structure is what defeats length-extension attacks: an attacker can’t extend the inner hash’s input without already knowing the key, because the outer hash reprocesses the result rather than exposing it directly.
What HMAC is used for
- API request signing. A client and server share a secret key; the client computes an HMAC over the request (method, path, body, timestamp) and sends it as a header. The server recomputes the same HMAC and compares. If they match, the request wasn’t tampered with and came from someone holding the key.
- Webhook verification. When a webhook provider sends you an event, it typically includes an HMAC signature computed with a secret only you and the provider know. Verifying it before trusting the payload confirms the request actually came from that provider and not from someone who guessed your webhook URL.
- JWT signing. HS256, one of the two common JWT signing algorithms, is literally HMAC with SHA-256. Anyone who holds the shared secret can both issue and verify tokens — which is why HS256 is a poor fit when multiple independent services need to verify tokens without all of them holding the signing secret.
- Data integrity in storage. Some systems attach an HMAC to cached or stored data as a tamper check, verifying the tag before trusting the contents on read.
Comparing the secret to the tag safely
A subtle but important detail: when a server recomputes an HMAC and compares it to the one it received, that comparison must run in constant time — a simple == on many languages’ string types short-circuits on the first mismatched byte, which leaks timing information an attacker can use to guess the correct tag one byte at a time. Cryptography libraries provide a constant-time comparison function for exactly this reason; always use it instead of a standard equality check when verifying a signature.
HMAC vs digital signatures
HMAC is symmetric: the same secret key both produces and verifies the tag. Digital signatures (RSA, ECDSA, Ed25519) are asymmetric: a private key signs, and a separate public key verifies. Each fits a different trust model.
| HMAC | Digital signature | |
|---|---|---|
| Key model | One shared secret | Private key signs, public key verifies |
| Who can verify | Anyone with the secret (can also forge) | Anyone with the public key (cannot forge) |
| Best for | Two parties that already share a secret | Verifying against many independent parties |
| Typical use | Webhook signing, HS256 JWTs, HMAC-based OTPs | RS256/ES256 JWTs, TLS certificates, code signing |
| Key distribution risk | Secret must stay confidential on both ends | Public key can be published freely |
If a token or message needs to be verified by parties you don’t fully trust with the ability to also produce valid tokens, an asymmetric signature is the better fit — that’s why identity providers issuing tokens to many relying parties typically prefer RS256 or ES256 over HS256.
The takeaway
HMAC proves message integrity and authenticity in one step by running a hash function over the message combined with a secret key through a specific nested construction, not a naive concatenation. It’s cheap to compute, doesn’t require key pairs, and underlies webhook signatures, HS256 JWTs, and countless internal API authentication schemes. The two things worth remembering: keep the shared secret confidential on both ends, and always compare tags with a constant-time function rather than ordinary string equality.
Keep reading
The Lycoris Team · · 5 min read How Digital Signatures Work
A digital signature uses a private key to prove a message's origin and integrity, and a public key lets anyone verify it — no shared secret required.
Chisato · · 4 min read OCSP vs CRL: How Certificate Revocation Works
OCSP and CRL are the two mechanisms browsers use to check if a TLS certificate has been revoked before its expiry date. Here's how each works.
Chisato · · 4 min read What Is a Zero-Knowledge Proof?
A zero-knowledge proof lets one party prove a statement is true without revealing why — the basis of privacy-preserving verification systems.