HMAC: Hash-Based Message Authentication
A hash alone can't prove a message wasn't tampered with — anyone can recompute it. HMAC fixes that by mixing in a secret key, becoming one of the most quietly essential building blocks in TLS, SSH, and beyond.
Interactive HMAC Visualizer
🔐 HMAC-SHA256
HMAC: Hash-Based Message Authentication
Introduction
A plain hash like SHA-256 proves data integrity against accidental corruption, but not against a deliberate attacker — anyone can recompute a hash and produce a matching one for a modified message, since hashing requires no secret. HMAC (Hash-based Message Authentication Code), standardized in RFC 2104, fixes this with a small, elegant construction: mix a secret key into the hashing process itself, so that only someone who knows the key can produce a valid authentication tag. It’s one of the most widely deployed cryptographic primitives in the world, quietly underpinning TLS, SSH, HKDF, PBKDF2, JWT tokens, and countless API authentication schemes.
Table of Contents
- Why Not Just Hash the Key and Message Together?
- How HMAC Works
- A Verified Example
- Security Properties
- Real-World Applications
- FAQ
- References
Why Not Just Hash the Key and Message Together?
The naive approach — compute Hash(key || message) — has a real, exploitable weakness against Merkle-Damgård-based hash functions like SHA-256: an attacker can perform a length-extension attack, appending additional data to the message and computing a valid new hash for the extended message, without ever knowing the key, simply by continuing the hash computation from the known intermediate state. HMAC’s specific double-hashing construction, detailed below, was deliberately designed to close this exact loophole.
How HMAC Works
HMAC(key, message) = Hash( (key ⊕ opad) || Hash( (key ⊕ ipad) || message ) )
Breaking this down:
- If the key is longer than the hash function’s internal block size, it’s first hashed down to fit; if shorter, it’s zero-padded out to the block size.
- ipad (“inner pad”) is the byte
0x36repeated to block length; opad (“outer pad”) is0x5crepeated the same way. - The key is XORed with ipad, concatenated with the message, and hashed — this is the inner hash.
- The key is XORed with opad, concatenated with the inner hash result, and hashed again — this outer hash is the final HMAC tag.
This double-hashing structure, with two different masked versions of the key, is what gives HMAC its formally proven security — including resistance to the length-extension weakness that a naive single hash-with-key approach would have.
Interactive Visualizer
The visualizer above runs genuine HMAC-SHA256 — real inner and outer padding, real double hashing — and was verified against a standard cryptographic library’s HMAC implementation before being published here. Try changing even one character of the message and watch the tag change completely.
A Verified Example
Using a simple demonstration case:
- Key: “key”
- Message: “The quick brown fox jumps over the lazy dog”
- HMAC-SHA256:
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd
Every correct HMAC-SHA256 implementation, including the one running in the visualizer above, reproduces this exact tag from these inputs.
Security Properties
HMAC’s security has been formally proven (Bellare, Canetti, and Krawczyk, 1996) to reduce directly to the security of its underlying hash function — as long as the hash function itself behaves like a good pseudorandom function, HMAC built on top of it inherits that security, with resistance to forgery even if an attacker can observe many valid (message, tag) pairs. This is a meaningfully stronger, more carefully analyzed guarantee than the naive “just hash the key and message” approach, which — beyond the length-extension weakness — lacks any comparable formal security proof at all.
Real-World Applications
- TLS: HMAC (or its AEAD-integrated equivalents) authenticates handshake messages and, in non-AEAD cipher suites, record data.
- HKDF and PBKDF2: both key derivation functions covered elsewhere on this site are built entirely on top of HMAC as their core primitive.
- JWT (JSON Web Tokens): the widely used
HS256JWT signing algorithm is literally HMAC-SHA256 applied to the token’s header and payload. - API authentication: many REST APIs (AWS’s request signing, webhook signature verification schemes, and others) use HMAC to let a client prove it holds a shared secret without transmitting that secret itself.
- SSH: uses HMAC-family constructions to authenticate the integrity of transmitted packets.
FAQ
Is HMAC encryption?
No — HMAC provides authentication and integrity (proving a message came from someone who knows the key and wasn’t altered), not confidentiality. It doesn’t hide the message content at all; it’s typically used alongside separate encryption, or as part of an AEAD construction like AES-GCM or ChaCha20-Poly1305.
Can HMAC use any hash function?
Yes — HMAC is generically defined over any suitable cryptographic hash function. HMAC-SHA256 is the most common choice today; older systems sometimes use HMAC-SHA1 or HMAC-MD5, though both underlying hash functions are individually considered broken for collision resistance (HMAC’s construction mitigates but doesn’t eliminate all concerns from using a weakened underlying hash).
What is a length-extension attack, and does HMAC prevent it?
It’s an attack against naive Hash(key || message) constructions where an attacker extends a message and computes a valid hash for the extended version without knowing the key, by continuing the hash computation from its known final state. HMAC’s inner/outer double-hashing structure specifically prevents this, which is a major reason HMAC exists as a distinct, carefully designed construction rather than everyone just concatenating a key onto their hash input.
Why does HMAC use two different padding constants (ipad and opad)?
Using two different, fixed masks ensures the inner and outer hash computations are cryptographically decorrelated from each other — an attacker learning something about the inner hash computation gains no direct advantage attacking the outer one, which is central to HMAC’s formal security proof.
Is HMAC-SHA256 quantum-resistant?
Yes, in the sense that matters practically — like AES, HMAC’s underlying security only weakens (not breaks) against Grover’s algorithm’s quadratic quantum speedup, and HMAC-SHA256 retains a comfortable security margin even accounting for that, unlike RSA, DH, or ECC, which Shor’s algorithm would break outright.
References
-
RFC 2104. “HMAC: Keyed-Hashing for Message Authentication.” IETF, 1997. Available at: https://datatracker.ietf.org/doc/html/rfc2104
-
FIPS PUB 198-1. “The Keyed-Hash Message Authentication Code (HMAC).” NIST, 2008.
-
Bellare, M., Canetti, R., and Krawczyk, H. “Keying Hash Functions for Message Authentication.” CRYPTO 1996 — the original paper with HMAC’s formal security proof.
-
Wikipedia. “HMAC.” Available at: https://en.wikipedia.org/wiki/HMAC