Password Storage
Why a leaked database still shouldn't give up your password.
What it does
The single rule of password storage: a server should never be able to tell you your own password. It keeps just enough to check a guess — never enough to recover the original. So at sign-up it doesn't store your password; it stores a one-way, salted, slow hash of it. At login it runs the same transform on what you typed and compares the results.
Done right, a stolen database is a pile of useless fingerprints. Done wrong, it's a spreadsheet of everyone's password.
Why hashing alone isn't enough
“Just hash it” sounds safe — a hash is one-way, after all. But a bare hash is deterministic, and that's the leak. The same password always produces the same digest, which hands an attacker two free wins: identical passwords are visibly identical, and a single rainbow table of common-password hashes reverses them all at once.
Toggle the leaked table below between bare SHA-256 and salted PBKDF2. Watch Alice and Bob — who picked the same password — and watch the rainbow table do its work:
not in the common-password table — yet
not in the common-password table — yet
not in the common-password table — yet
Alice and Bob chose the same password, so their stored hashes are identical — the leak reveals that. And a precomputed table cracks every common password instantly. Bare hashing is barely better than plaintext.
log in as carol — verified, never stored
The server compares hashes, not passwords. It could not tell you carol's password if it tried — it doesn't have it.
Salt, then slow it down
The fix is the previous page's two ideas, applied to storage. A unique salt per user makes every stored hash different — even when two people share a password — so collisions vanish and precomputed tables die. Then a deliberately slow hash (PBKDF2, or better, bcrypt / scrypt / Argon2) means each remaining guess costs real time. An attacker who steals the database still has to brute-force every account separately, slowly.
In the login box above, the server verifies carol's password without ever holding it. It re-derives the hash from her guess and the stored salt, and compares — that's all it can do, and all it should be able to do.
If a site can email you your password, run
A correctly built system cannot recover your password — it only stored a one-way hash. So “here is your password” in an email means they stored it in a form they can read, which means a breach hands it straight to an attacker. Real systems reset passwords (set a new one); they never retrieve the old one.
The hash isn't the last line — it's the last-but-one
Salted slow hashing buys time after a breach; it doesn't make weak passwords strong. A user who picks 123456 is still cracked quickly, salt or no salt. That's why the modern stack adds multi-factor authentication and breach monitoring on top — defense in depth, not a single clever hash.
What it's for
- Every login you've ever made — this is the standard server-side handling of account passwords.
- API keys & tokens at rest — the same store-the-hash pattern lets a service verify a secret it never keeps in readable form.
- Anywhere you verify a secret you shouldn't hold — the goal is always to prove knowledge without storing the thing itself.