Skip to content
Optimal Lab

Security · interactive

Storing passwords

Assume the user table leaks: it eventually does. What the attacker can do next depends entirely on how you stored the passwords. Hashes shown are illustrative; guess rates are rough single-GPU figures.

The leaked users table · SHA-256

userpassword column
alice0b14d5…e1f7 ← same as another user
bob0b14d5…e1f7 ← same as another user
carol5f2e88…41c0

Time to try every possible “8 random lowercase letters” password:

21 seconds

26⁸ ≈ 2×10¹¹ options

Fast hash: about 10 billion guesses a second on one GPU. Same password, same hash.

How passwords are stored

The user's password

Step 2 of 4

  1. 1

    Never store the password

    Store a one-way hash. At login, hash what the user typed and compare.

    Plain text turns a leak into instant account takeover everywhere the password was reused.

  2. 2

    Fast hashes are too fast

    SHA-256 is built for speed. A GPU tries billions of guesses a second, and identical passwords give identical hashes.

    alice and bob share a hash, so cracking one cracks both.

  3. 3

    A salt per user

    Random bytes mixed in before hashing: same password, different hash. Kills precomputed tables, but each guess is still cheap.

    Salts are stored next to the hash; they aren't secret.

  4. 4

    Use a slow password hash

    bcrypt, scrypt or Argon2 are salted and deliberately expensive, with a cost you raise as hardware gets faster. Logins barely notice; attackers do.

    • Plain textinstantly
    • SHA-25621 seconds
    • SHA-256 + salt21 seconds
    • bcrypt (cost 12)3.3 years