Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is crypt($pass, '$2y$09$salt') === crypt($pass, crypt($pass, '$2y$09$salt')) in PHP?

I'm ok really confused on the crypt() PHP function.

How does the following two crypt functions give the same output when the second crypt is clearly using an different 2nd argument? Diff salt means diff hash right?

echo crypt("password", '$2y$09$anexamplestringforsalt$')."\n<br>";
echo crypt("password", crypt("password", '$2y$09$anexamplestringforsalt$'))."\n<br>";

output:

$2y$09$anexamplestringforsale/.K.VdgECUVEd9N4ja3u1WtgPi5BXZq 
like image 932
user3388884 Avatar asked Mar 26 '14 17:03

user3388884


1 Answers

The reason is because the salt is part of the output of the hash that crypt provides.

$2y$09$anexamplestringforsale/.K.VdgECUVEd9N4ja3u1WtgPi5BXZq 

That is broken into several components:

  • 2y - algorithm identifier (bcrypt)
  • 09 - the cost parameter
  • anexamplestringforsale - the salt
  • /.K.VdgECUVEd9N4ja3u1WtgPi5BXZq - the hash

This results in the nice property of just being able to use the result hash directly as the salt in the verification call.

$hash = crypt($password, $salt);

if ($hash === crypt($password, $hash)) {

Now you don't need to store the algorithm, cost or salt separately. Just store them in the hash result directly. Simple.

Also, I'd highly suggest you use the simplified password hashing API, which was designed to specifically mitigate these issues: password_hash().

like image 143
ircmaxell Avatar answered Nov 16 '22 11:11

ircmaxell