2
votes

I understand that PHP's crypt() function works like so:

crypt($password,$salt);

And that to create a bcrypt hash(which is considered very secure) the format is:

crypt("$2y$15$password",$salt);

Where $2y specifies the use of bcrypt, and 15 is the number of rounds, and it should be above 10.

Here's my question. Running:

crypt("$2y$15$password");

in my understanding, generates a nice big random salt and adds it to the hash, and when comparing passwords, this is extracted automatically. This would mean that I wouldn't have to have a salt field in my table, or generate a salt independently. Is this secure and correct?

For example, when I run:

$test = "Hello";
echo crypt("$2y$15$test") . "\n";

I get:

 $6$R59d/nemygl0$/Gk6s57K2eFAkH4BWDGYhfdhbYGcqz.GRbD7qGDKOlhE5Lk.kgCoGQo/sDCCf1VDffdh7jtXPn/9rsexwrpFk1 

Where the first 6 refers to some algorithm number, the next bit between the two $ is the salt, and the bit after that is the hash. Is this correct?

Also, what is the syntax for comparing this hash to another for verification? Thanks.

2

2 Answers

2
votes

I think crypt as you're using it uses SHA-512.

You probably forgot to pass $test as parameter in your crypt().

According to php docs you should pass the password as first argument (without any prefix) and then pass the salt as second argument with the $2y$15 prefix and a 22 characters salt. E.g.

crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$');
0
votes

The function crypt() should be used like this:

$hashvalue = crypt($password, $cryptParams);

whereas the salt must be generated by yourself and is part of $cryptParams.

$bcryptAlgo = '$2y';
$cost = '$15';
$salt = '$' . functionThatGenerates22CharRandomSalt();
$cryptParams = $bcryptAlgo . $cost . $salt;

One of the difficulties is to generate a valid, unique and unpredictable salt. The best you can do is to read from the operating systems random source.

PHP 5.5 will have it's own functions password_hash() and password_verify() ready, to simplify this task. I strongly recommend to use this excellent api, there is also a compatibility pack available for earlier PHP versions. If you want to know more about how to use crypt, have a look at this article.

Your cost parameter of 15 is quite high, use it if you can afford this much of time, but today a number of 10 is ok.