Modern defenses
The salt
Rainbow tables work because raw hashing is predictable. The salt breaks this predictability in a simple and radical way.
Adding randomness: the salt
The principle: for each account, we generate a random and unique value, called the salt. Before hashing, we combine the password and the salt.
hash = hash( salt + password )
The salt is not secret: we store it in plaintext, right next to the hash in the database. Each row therefore contains a (salt, hash) pair.
+----------+--------------------+------------------------+
| user | salt (random) | hash |
+----------+--------------------+------------------------+
| alice | 8fk3Qz | hash("8fk3Qz" + pwd) |
| bob | pL9xR2 | hash("pL9xR2" + pwd) |
+----------+--------------------+------------------------+
Effect #1: no more identical hashes
Since the salt is unique per user, two people with the same password obtain different hashes:
Alice : hash("8fk3Qz" + "soleil2024") -> 71c0aa...
Bob : hash("pL9xR2" + "soleil2024") -> e934bd... (different!)
The attacker can no longer spot accounts that share a password, nor crack several accounts at once.
Effect #2: rainbow tables become useless
This is the major benefit. A rainbow table is precomputed for unsalted passwords. With a random salt, the attacker would have to build an entire table per possible salt value — which represents an astronomical amount of work, completely out of reach.
The "once and for all" precomputation collapses: the salt forces the attacker to redo the computation for each account, individually. Ready-made tables are no longer of any use.
What the salt does not do
Beware: the salt does not protect against an attack on a single targeted account. Against a specific victim, the attacker reads their (public) salt and launches brute force or a dictionary attack on that account. The salt prevents mass attacks and precomputed tables, but not individual persistence — that is the role of the slow functions in the next lesson.
Optional: the pepper
Some systems add a pepper: a global secret, identical for everyone, but stored elsewhere than in the database (in the code or a secure module). If only the database leaks, the attacker does not have the pepper. Unlike the salt, the pepper is secret and not stored next to the hashes.
In summary
- The salt is a random and unique value per account, added to the password before hashing.
- It is stored in plaintext next to the hash (it is not secret).
- Effect: two identical passwords produce different hashes.
- Rainbow tables become useless (one would be needed per salt).
- The pepper is a secret and global variant, stored outside the database.

