Search code examples
phphashpasswordspassword-hash

Verify password hashed and salted with password_hash


Let's hash and salt a password with:

<?php
$hash = password_hash('bonjour', PASSWORD_BCRYPT,  ['cost' => 12, ]);
// no salt option mentionned 
// then salt will be generated randomly, see password_hash documentation     
echo $hash;
?>

The result changes on each reload of the page, that's normal : the salt is randomly generated, it can be :

$2y$12$FlxBBjTjelKkGY.SJarlL.THUZBwcl7M6V35DmZmTmYJZRwhpRkIW
$2y$12$p2pkD116hBHNc/2nyQ2WyOkrn.h8xvWvM1.Lmvsnhms2Y6zsb.j1e
$2y$12$u4ipdQQM926jfanpXnwtkupv2CH/uWoPvK563tG7p.z35GcOBOZdS
etc.

In the previous code, the salt seems to be stored nowhere (am I wrong ?). But at the end password_verify is able to check the password with the hash, and it works with every result, regardless what the salt was.

<?php
echo password_verify('bonjour', '$2y$12$FlxBBjTjelKkGY.SJarlL.THUZBwcl7M6V35DmZmTmYJZRwhpRkIW') ? 'yes' : 'no';
// yes
echo password_verify('bonjour', '$2y$12$p2pkD116hBHNc/2nyQ2WyOkrn.h8xvWvM1.Lmvsnhms2Y6zsb.j1e') ? 'yes' : 'no';
// yes
?>     

Is it normal that password_verify is able to check the password without having to store the salt somewhere?


Solution

  • From the PHP.net manual

    Note that password_hash() returns the algorithm, cost and salt as part of the returned hash. Therefore, all information that's needed to verify the hash is included in it. This allows the verify function to verify the hash without needing separate storage for the salt or algorithm information.

    The salt is encoded in the hash, basically.