What is the difference between a keyed and an unkeyed hash function?
A keyed hash function (MAC/HMAC) requires a secret key and provides authenticity; an unkeyed hash function (MDC) needs no key and only detects modifications.
Keyed hash functions (e.g., HMAC-SHA256):
- Input: message $m$ + secret key $K$
- Output: $h(K, m)$ — the authentication tag
- Anyone with $K$ can compute and verify
- Provides: integrity + authenticity
Unkeyed hash functions (e.g., SHA-256):
- Input: message $m$ only
- Output: $h(m)$ — the hash/digest
- Anyone can compute the hash
- Provides: integrity detection only (if you have a trusted copy of the hash)
The catch — only against non-adversarial change: an MDC detects tampering only if the digest itself is trusted (delivered over a separate authenticated channel, signed, or stored where the attacker can't reach). If Eve can alter the message, she can just recompute $h(m')$ and replace the stored hash — the change is undetectable. So an unkeyed hash alone guards against accidental corruption, not an active attacker. Closing that gap is exactly what a keyed MAC (shared secret) or a digital signature (private key) does.
When to use which:
- MDC: File integrity checks (download verification), git commit hashes, password storage (with salt)
- MAC/HMAC: Authenticating API requests, verifying message integrity between parties who share a secret
HMAC construction: $\text{HMAC}(K, m) = H((K \oplus \text{opad}) \| H((K \oplus \text{ipad}) \| m))$ — it wraps the hash function with key material in a way that's provably secure.
Go deeper:
HMAC — the keyed construction and its security proof.
RFC 2104 — HMAC — the authoritative HMAC definition.