Password Storage Done Right
On this page
Storing passwords safely is a genuinely solved problem, yet still gotten wrong constantly. The answer is not clever: hash each password with a slow, salted, purpose-built algorithm so that a stolen database is not a stolen list of passwords. Everything else — plaintext, encryption, fast hashes — ranges from negligent to actively dangerous.
What is the right way?#
Use a modern password-hashing function that salts automatically and is deliberately slow:
| Algorithm | Notes |
|---|---|
| Argon2id | Current first choice; memory-hard |
| scrypt | Strong, memory-hard |
| bcrypt | Battle-tested, still acceptable |
These build on two ideas from the fundamentals: a unique salt per password, so identical passwords hash differently and rainbow tables fail; and deliberate slowness, so an attacker who steals the database can only guess a few thousand candidates per second instead of billions.
What must you never do?#
| Anti-pattern | Why it is dangerous |
|---|---|
| Plaintext storage | A breach is instant total compromise |
| Encryption (reversible) | One leaked key exposes every password |
| Fast hash (MD5, SHA-256) | Billions of guesses per second |
| Unsalted hashes | Rainbow tables crack them wholesale |
The distinction that trips people up is hashing vs encryption: passwords must be hashed, never encrypted, because you should never be able to recover them.
Correct password storage complements MFA and session management. More at the Web Security hub.
Frequently asked questions#
How should passwords be stored?
Never in plaintext and never encrypted. Store a hash produced by a slow, salted, purpose-built algorithm — bcrypt, scrypt, or Argon2. These automatically salt each password and are deliberately slow to compute, so even if the database is stolen, cracking the hashes is impractically expensive.
Why not use SHA-256 for passwords?
SHA-256 is a fast general-purpose hash, and speed is exactly what you do not want for passwords — attackers can compute billions of guesses per second against it. Password hashing needs a slow, memory-hard function like Argon2. Fast hashes are right for integrity checks, wrong for password storage.