Quiz Entry - updated: 2026.07.14
What is the difference between a salt and a pepper in password hashing?
Salt is unique per user and stored alongside the hash in the database. Pepper is a single application-wide secret that is NOT stored in the database — kept somewhere separate from the DB.
| Salt | Pepper | |
|---|---|---|
| Unique per | Each user | Whole application |
| Stored | In the database, with the hash | Not in the database — in the app config, env var, or HSM |
| Random? | Random, generated when password is set | Picked once at deployment time |
| Secret? | No — assumed leaked when the DB leaks | Yes |
| Purpose | Defeats rainbow tables; identical passwords across users get different hashes | Provides defence even if only the DB leaks — without the pepper the attacker can't crack hashes offline |
Combined storage on disk:
H( password || salt || pepper )
When the user logs in:
- Look up
(stored_hash, salt)for the username. - Compute
H(submitted_password || salt || pepper). - Compare against
stored_hash.
The threat models they protect against:
- Salt alone: protects against rainbow tables + cross-user identical-hash attacks. Doesn't help if the attacker has the DB and knows your hashing scheme.
- Pepper additionally: protects against the common breach scenario where only the database is stolen (e.g. SQL injection, leaked backup, contractor's laptop). The pepper lives on the application server or in an HSM — separate compromise required.
Tip: Argon2 includes a built-in random salt automatically. For pepper, two common implementations: (1) HMAC(password+salt, pepper_key) before Argon2, or (2) encrypt the Argon2 hash with the pepper as a key. Both keep the pepper out of the DB while still using strong primitives.