8

I think I'm missing something critical here. In the CPasswordHelper::hashPassword function we have lines:

$salt=self::generateSalt($cost);  
$hash=crypt($password,$salt);  

return $hash;

And in the CPasswordHelper::verifyPassword there is this line:

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

return self::same($test, $hash);

What about the salt? To my understanding its not even beeing kept, but it doesn't make any sense, so I'm guessing I didn't understand it completely.

trejder
  • 17,148
  • 27
  • 124
  • 216
user1908466
  • 503
  • 1
  • 8
  • 17

2 Answers2

38

CPasswordHelper works like PHP's functions password_hash() and password_verify(), they are wrappers around the crypt() function. When you generate a BCrypt hash, you will get a string of 60 characters, containing the salt.

// Hash a new password for storing in the database.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

The variable $hashToStoreInDb will now contain a hash-value like this:

$2y$10$nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |                     |
 |  |  |                     hash-value = K0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa
 |  |  |
 |  |  salt = nOUIs5kJ7naTuTFkBy1veu
 |  |
 |  cost-factor = 10 = 2^10 iterations
 |
 hash-algorithm = 2y = BCrypt

The salt you can find after the third $, it is generated automatically by password_hash() using the random source of the operating system. Because the salt is included in the resulting string, the function password_verify(), or actually the wrapped crypt function, can extract it from there, and can calculate a hash with the same salt (and the same cost factor). Those two hashes are then comparable.

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
2

The salt is being stored as part of the hash.

DaSourcerer
  • 6,288
  • 5
  • 32
  • 55
  • can you be a little more spacific? when I store the password in the `db` I crypt the text password with the salt and get some kind of a hash. now, when I want to verify if a password enter by a user is legal don't I need to crypt it with the same salt? If I'll crypt it with the hash won't I get something else? – user1908466 Dec 05 '13 at 09:26
  • As @martinstoeckli already pointed out, hashes generated by `CPasswordHelper` contain a `$` sign followed by the code for a selected algorithm, another `$`, the cost-factor (attention: If you see a 10, it actually means 2^10 iterations!), another `$`, a fixed number of characters being the salt followed directly by the actual hash. – DaSourcerer Dec 05 '13 at 13:57