HMAC (Hash-based Message Authentication Code)
A mechanism for message authentication that combines a cryptographic hash function with a secret key. It produces a fixed-length digest that can only be generated or verified by parties who hold the secret key, providing both data integrity and authentication. Defined in RFC 2104.
HMAC (Hash-based Message Authentication Code) is a mechanism for verifying both the integrity and authenticity of a message. It applies a cryptographic hash function to a combination of the message and a secret key, producing a MAC that can only be generated or verified by parties who know the key. Defined in RFC 2104, HMAC can use any cryptographic hash function — the most common variants are HMAC-SHA256 and HMAC-SHA512.
Construction
HMAC(K, m) = hash((K ⊕ opad) || hash((K ⊕ ipad) || m))
Where:
K = secret key (padded to block size)
m = message
opad = 0x5c repeated for block size
ipad = 0x36 repeated for block size
|| = concatenation
⊕ = XOR
The two-pass construction makes HMAC immune to length-extension attacks that affect raw SHA-2 hashes.
Computing HMAC-SHA256
async function hmacSha256(key, message) {
const enc = new TextEncoder();
const cryptoKey = await crypto.subtle.importKey(
"raw", enc.encode(key),
{ name: "HMAC", hash: "SHA-256" },
false, ["sign"]
);
const sig = await crypto.subtle.sign("HMAC", cryptoKey, enc.encode(message));
return [...new Uint8Array(sig)].map(b => b.toString(16).padStart(2, "0")).join("");
}
import hmac, hashlib
mac = hmac.new(
key=b"secret-key",
msg=b"message",
digestmod=hashlib.sha256
).hexdigest()
# Always use constant-time comparison to prevent timing attacks
hmac.compare_digest(received_mac, computed_mac)
Use Cases
- Webhook signatures: GitHub, Stripe, and most webhook providers sign payloads with HMAC-SHA256
- JWT HS256: the
HS256algorithm in JWT is HMAC-SHA256 - API request signing: AWS Signature Version 4 uses HMAC-SHA256 iteratively
- Cookie integrity: sign cookie values to detect tampering
- TOTP/HOTP: time-based and counter-based one-time passwords use HMAC-SHA1
HMAC vs Raw Hash
A raw hash cannot authenticate: anyone can compute SHA-256(message). HMAC requires the secret key to produce the same digest, proving the signer held the key. Never use SHA-256(key + message) as a MAC — it is vulnerable to length extension attacks. Use HMAC instead.
Generate and verify HMACs with the HMAC Generator Tool.