Hash, Salt, and HMAC
Hash functions are fundamental tools in security. They transform any input into a fixed-size output — called a digest — in an irreversible way.
What is a Hash Function
Essential properties:
- Deterministic: same input, same output.
- Irreversible: you cannot recover the input from the output.
- Avalanche effect: a minimal change in input completely changes the output.
- Collision resistant: different inputs produce different outputs (in practice).
echo -n "password123" | sha256sum
# ef92b778bafe771e89245b89ecbc08a44a4e166c06659911881f383d4473e94f -
Modern algorithms: SHA-256, SHA-384, SHA-512, SHA-3. Avoid: MD5, SHA-1 — broken for security purposes.
The Problem with Unsalted Hashes
Plain hashes are vulnerable to rainbow tables — precomputed tables that map hashes back to common passwords.
sha256("123456") = 8d969eef6ecad3c29a3a629280e686cf...
# Any rainbow table database reverses this in seconds
Salt: Guaranteed Uniqueness
A salt is a random value added to the input before computing the hash. Each user gets their own salt.
salt = "xK9#mQ2p" (randomly generated per user)
hash = sha256("password123" + salt)
The salt is stored in plaintext alongside the hash. Its goal is not to be secret — it is to make dictionary attacks impractical.
import hashlib, os
salt = os.urandom(16)
password = b"my_password"
digest = hashlib.sha256(salt + password).hexdigest()
# Store: salt (hex) + digest
For passwords, prefer derivation functions like bcrypt or argon2 (covered in lesson 6).
HMAC: Message Authentication
HMAC (Hash-based Message Authentication Code) combines a hash with a secret key. It guarantees that a message was not altered and that whoever signed it knows the key.
HMAC(key, message) = hash(key ⊕ pad || hash(key ⊕ pad || message))
In practice:
import hmac, hashlib
key = b"secret_key"
message = b"payment request: $500"
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
print(mac)
# Receiver recomputes and compares — if different, message was tampered
HMAC use cases: session tokens, webhooks (payload verification), REST APIs.
Summary
| Technique | Purpose | Secret Required |
|---|---|---|
| Hash | Integrity | No |
| Salt | Hash uniqueness | No (it’s public) |
| HMAC | Authentication + integrity | Yes (key) |