Password attacks, hashing, and the three jobs of a salt
◈ 8 cardsThe eight attack strategies with the countermeasure that answers each, why a password file is hashed rather than encrypted, and the three separate things a salt buys — only one of which most answers name.
Eight ways in
Passwords are still the front door of most systems, so the ways through that door have been catalogued. Learn them as eight strategies, each with the countermeasure that answers it — the pairing is the examinable structure, and it is also how you argue for a password policy without hand-waving.
- Offline dictionary attack. The attacker obtains the password file itself and, at leisure, hashes candidate passwords until the digests match. Counter: protect the file; run intrusion detection so you learn it was taken; reissue every password fast when it is.
- Specific account attack. Hammer one account with guesses. Counter: account lockout after a small number of failures — five is typical practice.
- Popular password attack, better known as spraying. Try one very common password against thousands of user IDs. Counter: forbid common passwords outright, and watch source addresses and client cookies for the submission pattern. Lockout does not help here, and that is the point of the strategy: one attempt per account never trips a per-account counter.
- Targeted guessing from personal knowledge. Learn the holder's birthday, pet, team, and the organisation's own password policy, then guess inside that space. Counter: policy on minimum length, character set, prohibition of well-known identifiers and change interval — plus training and enforcement.
- Workstation hijacking. Wait for an unattended logged-in machine. Counter: automatic logout on inactivity; intrusion detection on a change in behaviour.
- Exploiting user mistakes. Assigned passwords get written down. Passwords get shared to swap a file. Users get socially engineered. And shipped default administrator passwords go unchanged. Counter: training and intrusion detection — and, counter-intuitively, sometimes a simpler password combined with a second authentication mechanism, which is easier to comply with than an unusable rule.
- Exploiting multiple password use. The same password on a dozen devices, so one breach is twelve. Counter: policy forbidding it.
- Electronic monitoring. Eavesdropping the password as it crosses a network.
Why the file is hashed and not encrypted
The standard scheme stores, per user, a salt in plaintext and a hash computed over the salt concatenated with the password. Verification re-hashes the supplied password with the retrieved salt and compares. Two design choices in that sentence are worth defending explicitly, because both are asked.
First, hashed, not encrypted. Encryption is reversible: the system that can check your password can also recover it, which means a key exists somewhere that turns the whole file back into plaintext, and any administrator, backup tape, memory dump or key-management slip that exposes that key exposes every password at once. A hash has no inverse and no key to lose. The system never needs to know your password, only to recognise it — so it should not be built so that it can know it.
Second, the hash is deliberately slow. A general-purpose hash is optimised to be fast, which is exactly the wrong property here: the attacker's cost is per candidate and yours is once per login. An iterated construction such as PBKDF2, with a cost parameter, moves that trade in your favour by a factor you choose.
Worked example — one stolen file, twice
A file holds 4,096 accounts. The attacker steals it and mounts an offline dictionary attack with a list of 10 million candidates.
Unsalted. Hash each candidate once: 10 million hash operations. Compare each digest against all 4,096 stored values — a lookup, essentially free. Every account is attacked simultaneously, because one hash of sunshine tests every user at once. Worse, the attacker can compute that table before stealing the file, which is what a rainbow table is. And a glance at the file tells them which accounts share a password: identical hashes, side by side.
Now add a distinct salt per account. sunshine no longer has one digest; it has 4,096, one per salt in this file. The 10-million-candidate list must be hashed once per salt: 10 million × 4,096 ≈ 41 billion hash operations. Nothing precomputed survives, because the attacker did not know the salts in advance. And two users who both chose sunshine now store completely different digests, so the file no longer leaks reuse — within this system, or across two systems the same person uses.
More generally, a b-bit salt multiplies bulk offline work by 2^b and destroys precomputation entirely.
Now the sharp question, which is where marks are lost. Has the salt made any individual password harder to guess? No. Ask what it costs to attack one named account: the attacker reads that account's salt out of the file — it is stored in the clear, right beside the hash — and hashes 10 million candidates with it. Ten million operations, exactly as before. Not one operation more.
So the salt does not raise the per-guess cost. What it destroys is the attacker's amortisation: the ability to spend work once and spend it against everybody. That is why growing the salt from 12 bits to 48 cannot "defeat crackers entirely" — it makes bulk cracking and precomputation hopeless while leaving a targeted attack on a weak password untouched.
What the UNIX schemes actually chose
The historical parameters are worth carrying, because they show the cost parameter being tuned over three decades. crypt(3): passwords truncated to 8 characters, giving a 56-bit key, a 12-bit salt, and 25 iterations of a modified DES over a zero block, rendered as 11 characters. A 12-bit salt is a factor of only 4,096 — adequate in 1979 and inadequate now; it survives for compatibility, not for security. MD5-crypt: unlimited password length, a salt up to 48 bits, a 128-bit output, and a 1,000-iteration inner loop. bcrypt: up to 55 characters, a 128-bit salt, a 192-bit output, and — the important innovation — a tunable cost, so a site can make privileged accounts more expensive to attack than ordinary ones and can raise the cost again as hardware improves.