These slides are from a talk that I did at PHP Benelux 2013 ( http://conference.phpbenelux.eu/2013/ ).
In this talk, I go over the progression of password storage techniques, and weaknesses of each method. Eventually, we build up to the final secure implementations, and the current methods used to attack them.
11. What's A Cryptographic Hash?
Like a fingerprint.
One-way.
- Easy and efficient to compute
- Very inefficient to reverse
- (Practically impossible)
- Very hard to create collision
- (new input with same output)
12. MD5
What's the problem now?
SQL-Injection still gives us hash
But the hash is one-way, how can we attack it?
15. Lookup Table
Google is a great example
Maps hash to password directly
Database Table:
hash | password
--------------+-----------
"5f4dcc3b..." | "password"
"acbd18db..." | "foo"
16. Lookup Table
Lookups are CPU efficient.
Require a LOT of storage space
- (Very space inefficient)
All passwords <= 7 chars (95^7, 70 Trillion)
Requires 1.5 PetaBytes
- In Most Optimal Storage Format
21. Rainbow Table
Time/Space Tradeoff
- Slower than a Lookup Table
- Uses Much less storage
Most (99.9%) passwords <= 7 chars
Requires only 64 GB
- Chain length of 71,000
24. Salted MD5
git checkout salted-md5
Uses the MD5 Cryptographic Hash function.
But adds a random salt UNIQUE per user.
md5($salt . $password)
hash('md5', $salt . $password)
25. Salts
Must be unique!
- Per Hash
- Globally
Should be random
- Strong!!!
- Reasonably long (at least 64 bits)
26. Salted MD5
What's the problem now?
SQL-Injection still gives us hash
- And the salt
But the salt defeats rainbow tables...
28. What's A Cryptographic Hash?
Like a fingerprint.
One-way.
- Easy and efficient to compute
- Very inefficient to reverse
- (Practically impossible)
- Very hard to create collision
- (new input with same output)
29. What's A Cryptographic Hash?
Like a fingerprint.
One-way.
- Easy and efficient to compute
- Very inefficient to reverse
- (Practically impossible)
- Very hard to create collision
- (new input with same output)
32. Brute Forcing
Multiple Ways To Attack
- Mask Based (permutations)
- Dictionary Based
- Combinator Based
- Combinations of dictionary words
- Fingerprint Based
- Combinators applied with permutations
- Rule Based
- Takes input password and transforms it
33. Brute Forcing
Salted MD5
2012 Macbook Pro:
- md5: 33 million per second
- sha256: 20 million per second
Mask Attack:
6 char passwords: 5 hours
7 char passwords: 22 days
Entire English Language: 1.8 seconds
"LEET" Permutations: 1 hour
39. MD5 IS Broken!
But No Other Primitive Hash Is Not!!!
sha1≈ md5
sha256 ≈ md5
sha512 ≈ md5
whirlpool ≈ md5
ALL raw primitive hashes are broken for
password storage.
41. Iterated MD5
git checkout iterated-md5
Uses the MD5 Cryptographic Hash function.
But adds a random salt UNIQUE per user.
And iterates a lot of times
do {
$h = md5($h . $salt . $password)
} while($i++ < 1000);
48. BCrypt
git checkout bcrypt
Uses the standard BCrypt algo
- based on Blowfish cipher
Same execution time,
Much harder to run on GPU
crypt $2a$
49. Brute Forcing
BCrypt
25 GPU Cluster
- BCrypt: 70,000 per second
6 char passwords: 120 days
7 char passwords: 31 years
8 char passwords: 3000 years
Entire English Language: 14 minutes
50. A Note On Cost
BCrypt accepts a "cost" parameter
Must be tuned per server!
- Target about 0.25 to 0.5 second runtime
- Cost of 10 is a good baseline
- Cost of 11 or 12 is better
- If you have decent hardware.
51. PHP 5.5 Password Hashing API
git checkout password-compat
A thin wrapper over crypt()
- Simplifies implmentation
- Strong random salt generation
- Can specify cost as int option
password_hash($pass, $algo, $opts)
password_verify($pass, $hash)
github.com/ircmaxell/password_compat
54. Encrypted BCrypt
git checkout bcrypt-with-encryption
Hash with BCrypt,
Then encrypt result with AES-128.
Requires key storage for the app.
- Not trivial
Use only if needed!
- BCrypt alone is typically sufficient
55. Brute Forcing
Encrypted BCrypt
Attack requires low level server compromise!
- SQL Injection is not enough!
localhost/codeinject
- Simulates code injection that reads source
Any low level compromise
Is No Worse than raw BCrypt
- BCrypt is the baseline.
57. The Future
scrypt
- Sequential Memory Hard
- Uses a LOT of memory (32mb / hash)
- Harder to brute-force than bcrypt
But it's VERY new
- In cryptography terms at least
- Not proven enough for use (yet)
58. The Future
Password Hashing Competition
- Currently being setup
- Aims to pick "standard" password hashing
algorithm
- A community effort
59. The Future
Brute Forcing Word Lists
- Complex combinations of words
- "horse correct battery staple"
Brute Forcing Grammar
- "I don't want no cookies"
Brute Forcing Structures
- URLs, Email Addresses, URLs, etc