Skip to content

How should you store user passwords?

Short answer

Never store passwords in plaintext or reversibly encrypted, and never with fast general-purpose hashes like MD5 or SHA-256. Use a slow, memory-hard password hashing function — Argon2id (preferred) or bcrypt — with a unique random salt per password and a tuned work factor, so an attacker who steals the database cannot feasibly crack the hashes.

Passwords must be stored so that even an attacker who steals the entire database cannot recover them. That single requirement rules out plaintext and rules out reversible encryption — if your server can decrypt them, so can an attacker who takes your key. The answer is one-way password hashing, but with the right kind of hash.

Why not a fast hash like SHA-256?

General-purpose hashes are designed to be fast, which is exactly wrong here. Modern GPUs compute billions of SHA-256 hashes per second, so a stolen database of SHA-256 password hashes can be cracked at scale, especially for common passwords. You want a function that is deliberately slow and resource-intensive.

Use a password hashing function

  • Argon2id — the modern winner of the Password Hashing Competition; memory-hard, which resists GPU/ASIC cracking, with tunable memory, time, and parallelism parameters. Preferred for new systems.
  • bcrypt — battle-tested, with a configurable cost factor you raise over time as hardware improves. A solid choice.
  • scrypt / PBKDF2 — acceptable where the above are unavailable (PBKDF2 needs a high iteration count and is FIPS-friendly).

Salts (and peppers)

A salt is a unique, random value stored alongside each hash. It ensures two users with the same password get different hashes, which defeats precomputed rainbow tables and stops an attacker from cracking many accounts at once. (bcrypt/Argon2 generate and embed the salt for you.) An optional pepper is a secret added to all passwords and kept outside the database — e.g. in an HSM or app config — so a database-only leak is not enough.

Tune and migrate

Set the work factor so a single hash takes a meaningful fraction of a second on your hardware, and raise it over time. Plan to rehash on next login when you upgrade parameters.

Interviewers look for "slow, salted hash," naming Argon2id or bcrypt, rejecting encryption and fast hashes, and explaining why the salt matters (rainbow tables / identical passwords).

Likely follow-ups

  • Why is a per-user random salt necessary even with a strong hash?
  • What is a pepper and where is it stored differently from a salt?
  • Why are MD5 and SHA-256 bad choices for password storage?

Sources

Get 100 cybersecurity interview questions + answers

Drop your email and we'll send you the free PDF pack and the flashcard deck.

No spam. Unsubscribe anytime.