How should passwords be stored, and why use bcrypt/scrypt/argon2 over fast hashes?
Short answer
Store passwords using a deliberately slow, salted, adaptive password-hashing function — bcrypt, scrypt, or Argon2 — never a fast general-purpose hash like SHA-256 or MD5. Fast hashes are built for speed, so attackers with GPUs can test billions of guesses per second against a leaked database. Slow hashes have a tunable work factor (and memory cost) that makes each guess expensive, keeping brute force impractical even after a breach.
This is a make-or-break appsec question. The wrong answer ("we SHA-256 the password") sounds responsible but is exactly the mistake that turns a database leak into mass account takeover. The insight is that password hashing wants to be slow.
Why fast hashes fail
SHA-256, SHA-1, and MD5 are designed to be fast — that's a virtue for file integrity, where you hash gigabytes quickly. But speed is a liability for passwords. When an attacker steals a hashed-password table, they crack it offline, and with modern GPUs they can compute billions of fast-hash guesses per second. Combined with leaked wordlists and the reality that users pick predictable passwords, most fast-hashed passwords fall in hours. Salting helps against precomputation but does nothing about raw guessing speed.
Why slow, adaptive hashes win
Purpose-built password hashes deliberately cost a lot per evaluation:
- bcrypt has a tunable work factor (cost) you raise over time as hardware improves; it's been battle-tested for decades.
- scrypt adds memory hardness, forcing each guess to consume significant RAM, which blunts cheap parallel GPU/ASIC cracking.
- Argon2 (the Password Hashing Competition winner) tunes time, memory, and parallelism independently and is the modern default recommendation.
The shared idea: make a single guess take, say, 100 ms instead of a nanosecond. That's invisible to a legitimate login but multiplies an attacker's cost by orders of magnitude, so even a leaked database resists cracking. Salts (unique per user) are still mandatory on top, to stop rainbow tables and identical-hash leaks.
Why not encrypt instead?
Encryption is reversible, which means the key exists somewhere — and if the key is compromised, every password is recovered instantly. Hashing is one-way by design; you verify by re-hashing the input, never by decrypting. You should never need the plaintext back.
What interviewers look for
Naming bcrypt/scrypt/Argon2, explaining the slow-by-design / work-factor rationale, salting on top, memory-hardness as a bonus, and a firm "hash, don't encrypt" with the reasoning.
Likely follow-ups
- Why is being fast a weakness for a password hash but a strength for a file checksum?
- What does Argon2's memory-hardness defend against that bcrypt does not?
- Why should you never encrypt (reversibly) stored passwords?