Part II · 2 — Hash, MAC, and KDF

draft

Encryption protects the secret; hash, MAC, and KDF protect integrity, authorship, and the keys themselves. They are the most reused primitives — and the most misused (passwords in SHA-256 "because it's secure" is a classic mistake).


2.1 Cryptographic hash functions

A hash compresses an input of any size into a fixed-size digest (e.g., 256 bits). To be cryptographic, it needs three properties:

Property Meaning If broken…
Preimage resistance Given a digest, it is infeasible to find an input that generates it. Breaks passwords, commitments.
2nd-preimage resistance Given an input, it is infeasible to find another with the same digest. Forges documents.
Collision resistance It is infeasible to find any two inputs with the same digest. Breaks signatures (it was the end of MD5 and SHA-1).

Avalanche effect: flipping one input bit changes ~half the digest bits.

Hash: one-way function with avalanche effect


2.2 Which hashes to use (2026)

Hash Verdict
MD5, SHA-1 broken (practical collisions). Only for non-adversarial checksums.
SHA-256 / SHA-512 (SHA-2) ✅ solid standard, ubiquitous.
SHA-3 / Keccak ✅ different design from SHA-2 (sponge) — a good hedge.
BLAKE3 ✅ very fast, parallelizable; great for file integrity.

A hash is not for storing passwords. It is fast on purpose — which helps the attacker test billions per second. Passwords require a slow KDF (section 2.5).


2.3 MAC: integrity with authorship

A hash guarantees that the data did not change — but anyone can recompute the hash of altered data. A MAC (Message Authentication Code) adds a secret key: only someone who has it produces a valid tag. It proves integrity and origin (among those who share the key).

  • HMAC — builds a MAC from a hash (HMAC-SHA-256). Mature, standard.
  • Poly1305 — fast MAC, used in AEAD with ChaCha20.

Remember the distinction from Part I: a MAC uses a shared key (it gives no non-repudiation); a signature uses a private key (it does). And always compare tags in constant time — comparing byte by byte with early exit becomes a timing side channel.


2.4 KDF: deriving keys from other keys

A KDF (Key Derivation Function) produces keys from other material. Two distinct uses:

  • Key-material derivation — from a high-entropy secret

    (e.g., the result of a Diffie-Hellman), generate several subkeys. Use HKDF (HMAC-based KDF): extract (concentrates the entropy) + expand (generates bytes).

  • Stretching low entropy — predictable material needs a deliberately

    expensive KDF — that is the case for passwords, below.


2.5 Password hashing: the special case

Passwords have low, human entropy. Storing them requires a function that is slow and memory-hard, plus a salt unique per password:

Function Note
Argon2id ✅ current recommendation (resistant to GPU/ASIC via memory cost).
scrypt ✅ good alternative with memory cost.
bcrypt ✅ acceptable (solid legacy), without memory cost.
PBKDF2 ⚠️ only when required by a standard; configure high iterations.
Raw SHA-256 ❌ too fast — breakable en masse.
  • Salt — a public random value, unique per password, so that equal

    passwords generate different hashes and break rainbow tables. Stored alongside.

  • Pepper — a system-wide fixed secret, applied to all passwords and not

    stored in the database; it vanishes with the secret if the database leaks on its own.

Rule: password → Argon2id (with a per-user salt). Key material from a handshake → HKDF. Never swap one for the other.


Dense reference: the complete catalog of hashes (BLAKE2, SHA-3, RIPEMD, Streebog, SM3), HMAC, and KDFs is in 06-hash-and-mac. Next: the leap to asymmetric cryptography — where the two sides stop needing a prior shared secret.