You're deciding how to store user passwords. What's the correct approach?
Short answer
Password storage needs a deliberately slow, salted, memory-hard hash — bcrypt, scrypt, or Argon2 — so cracking stolen hashes is expensive and rainbow tables don't apply. A fast hash like SHA-256 is trivially brute-forced at scale; reversible encryption means one key compromise exposes every password at once; and plaintext is indefensible no matter how locked down the database is. Choose Argon2id (or bcrypt) with a tuned work factor and a unique per-user salt.
Storing passwords is a problem with a settled answer, and interviewers ask it to see whether you reach for the purpose-built primitive or one that merely sounds cryptographic. The correct choice is a slow, salted, memory-hard password hash: Argon2 (id variant), bcrypt, or scrypt.
Why slow-and-salted is the right tool
These functions are designed for credential storage. They are deliberately expensive to compute (a tunable work factor / memory cost), so an attacker who steals the hash database can only test guesses slowly — turning billions-per-second GPU cracking into a thousands-per-second crawl. A unique per-user salt ensures identical passwords produce different hashes, which defeats precomputed rainbow tables and prevents an attacker from cracking many accounts at once. Argon2's memory-hardness further blunts GPU and ASIC attacks.
Why each alternative fails
- SHA-256 is a fast, general-purpose hash — exactly the wrong property here. Modern hardware computes billions of SHA-256 hashes per second, so stolen hashes fall quickly, and unsalted ones fall to rainbow tables instantly.
- AES-encrypting passwords makes them reversible: the server must hold the key, so a single key compromise (or a malicious insider) exposes every password in plaintext. You also never need to recover the original password — only to verify it — so reversibility is pure downside.
- Plaintext "but lock down the database" is indefensible. One backup leak, SQL injection, or misconfigured replica and every credential is gone. Database ACLs are not a substitute for not storing the secret.
What a strong answer adds
Name Argon2id (or bcrypt) with a tuned cost and per-user salt; mention an optional pepper (a secret key kept outside the database) as defense in depth; and note that you'd rehash on login to migrate legacy fast-hash data and raise the work factor over time as hardware improves.
Likely follow-ups
- What work factor or memory/time parameters would you pick for Argon2id, and why tune them?
- Why does a per-user salt defeat rainbow tables, and what extra value does a pepper add?
- How would you migrate millions of existing SHA-256 hashes to Argon2 without forcing a reset?