Related questions:
Am I using PHP’s crypt() function correctly?
Password storage hash with SHA-512 or crypt() with blowfish (bcrypt)
I’m trying to figure out how I should safely store a password using PHP. After a little reading I’ve identified that I should use crypt() instead of hash() and that I should use either the blowfish (bcrypt) or SHA-512 algorithms, with I believe bcrypt being recommended more often, though there is significant support for SHA-512 based algorithms, too.
There are also many suggestions that my salt should be as random as possible, with many suggestions to use openssl_random_pseudo_bytes() over the core rand() and mt_rand().
My main questions are:
-
If I choose to use bcrypt, what load factors should I consider using? I noticed that for PHP 5.5 the default load factor in the new password API is 10 so I would imagine I would want at least that value.
-
How does the load factor correlate to password safety? From what I understand the algorithm will iterate
2^load_factortimes, but I’m more interested in how this translates into safety against brute force cracking methods. What does it mean to be “safe”? Does it take 10 years to crack? 5 years? 1 year? -
Why should I pick bcrypt over a SHA-512 based method (or vise-versa)? I’ve heard that SHA-512 is designed to be a fast hashing method so over time it won’t hold up as well as bcrypt. Is this true? Both methods have salt parameters which allow crypt to iterate multiple times.
-
To the best of my knowledge, I implemented the following test code which generates a bcrypt salt. Is the recommended method? Is there a better way to do it?
_
function gen_salt($cost)
{
return "$2y$" . $cost . "$" . str_replace('+', '.', base64_encode(openssl_random_pseudo_bytes(22)));
}
So based off of the comments I created a simple benchmark to test how long various hashing methods take.
Benchmark results (time in seconds):
Ran on my laptop with an i5-m430:
All things being equal, it takes a much higher number of iterations for the SHA-512 method vs. bcrypt to take the same amount of time. That being said I’m guessing that any method which takes at least a tenth of a second is more than sufficient.