Glossary

HMAC

HMAC (Hash-based Message Authentication Code) is a construction that combines a cryptographic hash function with a secret key to produce a tag proving both that a message wasn't altered (integrity) and that it came from someone holding the key (authenticity). It's specified in RFC 2104, and works with any underlying hash — HMAC-SHA256 and HMAC-SHA1 are the common names for HMAC built on SHA-256 or SHA-1.

How it works

A plain hash of a message proves only integrity: anyone can recompute SHA256(message) and compare it, so it says nothing about who produced it. HMAC fixes this by mixing a shared secret key into the hash computation itself, roughly: HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m)), where K' is the key padded to the hash's block size and opad/ipad are fixed constants. The result is a tag that only someone with the same key K can reproduce or verify — an attacker who can see the message and its HMAC still can't forge a valid HMAC for a different message without the key.

This is exactly the mechanism behind a JWT's HS256 signature, and it's the standard way services like Stripe and GitHub let webhook receivers verify that a payload really came from them: the sender computes an HMAC-SHA256 over the raw request body using a shared secret and sends it in a header; the receiver recomputes it locally and compares.

Example:

HMAC-SHA256("The quick brown fox jumps over the lazy dog", key="key")
= f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

Common pitfalls

  • Comparing HMAC tags with a naive == string comparison can leak timing information; use a constant-time comparison function to avoid timing attacks.
  • The security of HMAC depends entirely on keeping the key secret — a leaked webhook secret lets anyone forge valid signatures.
  • HMAC provides integrity and authenticity, not confidentiality — the message itself is still sent in plain text alongside the tag.
  • HMAC-MD5 and HMAC-SHA1 are still considered acceptably secure as keyed constructions even though plain MD5 and SHA-1 are broken for unkeyed hashing — but HMAC-SHA256 is the safer modern default with no such caveat.

Related terms

  • SHA-256 — the most common underlying hash function for HMAC today (as in HS256).
  • JWT — signs its header and payload with HMAC (in the HS256 variant) to prove the token wasn't tampered with.
  • Base64 — HMAC output is raw bytes, usually rendered as hex or Base64 for transport in a header or token.

See also

  • Tool: Hash Generator — compute the underlying SHA-256 or MD5 digests that HMAC wraps, useful for understanding or manually verifying an HMAC construction.