No. 04 — Lab 04

Password

storage

If a site's database leaks, the way passwords were stored decides how much damage follows. This lab shows the common mistake, the fix, and what the fix costs, using a short Python script with no dependencies. Every block below is real output.

857K×How much faster MD5 is than scrypt here
128 MBMemory each scrypt hash needs
16Random salt bytes per user
600KPBKDF2 rounds OWASP recommends

01 — The mistake

Same input, same hash

Two users, alice and bob, pick the same weak value. The site stores a fast, unsalted hash of it, the way many old systems did.

Python
python password-hash-demo.py plain
alice  MD5     f065d609e55983bc6087c073c91c9bc7
alice  SHA-256 323725e8eff4df0a4974d6ea8c73017aa6467d94e09382745b7a988cec0fba0a
bob    MD5     f065d609e55983bc6087c073c91c9bc7
bob    SHA-256 323725e8eff4df0a4974d6ea8c73017aa6467d94e09382745b7a988cec0fba0a

Same input, same hash. Anyone reading the database can see alice and bob chose the same
value, and one precomputed table of hashes works against every account.

02 — The fix

A random salt and a slow hash

Each user gets their own random salt, and the hash is scrypt, which is deliberately slow and memory-hungry. Checking a login recomputes the hash with the stored salt and compares the two in constant time.

Python
python password-hash-demo.py salted
alice  scrypt$131072$8$1$a7b59e514687af0791836e882ec36e5e$68406f17618695038c0b63b5963288147d034f07d6427adc7573b0683fe0c9df
bob    scrypt$131072$8$1$3ba2eceffb43af353b1bfacc2d563021$7660b0d06d231cd9e673305742df1bc3042d33f8beaf1c9180415681c07ea4c9

alice, correct input : True
alice, wrong input   : False

Same input, different stored values. Each record carries its own random 16-byte salt,
and the cost settings, so the format can be upgraded later without breaking old records.

03 — The cost

How fast is each method?

The same script times each method on this machine. The point is not the exact numbers, which depend on the computer, but the gap between them.

Python
python password-hash-demo.py speed
MD5                                     2,380,385.3 per second
SHA-256                                 1,933,786.5 per second
PBKDF2-SHA256, 600,000 rounds                  10.4 per second
scrypt, N=131072, r=8, p=1                      2.8 per second

On this machine MD5 is 856,577 times faster than scrypt.
A login takes a fraction of a second either way. Anyone who has to test guesses pays that
cost for every single guess.

04 — Result

What to use instead

Fast hashes are built to be fast. MD5 and SHA-256 are great for checking files, as in Lab 01, and wrong for passwords, because speed helps whoever is testing guesses, not the defender. A password hash should be slow and memory-hungry on purpose.

05 — Run it yourself

Same script, your machine

Download the script and run the three commands above with Python 3.8 or newer. Use python3 on Linux and macOS. The salts are random, so your stored values will differ from mine, and the timings depend on your computer. The gap between the methods will not.


←forensicsPrevious

All labs