Understanding how salt is generated/used in bcrypt password_hash Understanding how salt is generated/used in bcrypt password_hash php php

Understanding how salt is generated/used in bcrypt password_hash


The salt is, as documented on http://us2.php.net/crypt, 22 characters and not 21.

<?php$key = 'password';$hash = password_hash($key, PASSWORD_BCRYPT);$salt = substr($hash, 7, 22);$rehash = password_hash($key, PASSWORD_BCRYPT, ['salt' => $salt]);if ($hash == $rehash) {  echo 'ok', PHP_EOL;}

The last 2 in the salt5678901234567890123456789012 salt changing to an u is just some magic in crypt blowfish.


You seem to misunderstand how password hashing and salts are supposed to work.

The salt is never sent to the client. It is generated (or manually specified) only once when the password is created. Its purpose is to randomize the output of the hash function, so that when the database gets into the wrong hands it is not possible to get users passwords by comparing the output to rainbow tables.

When the user uses his password to login the password is sent from the client to the server unhashed (but usually over https). The password comparing function then fetches the stored hash+password, gets the salt from it, appends the salt to the user input, calculates the hash and then compares that to the hash from the database.

Maybe the project you're on has a bad implementation of salts. In fact, one of the reasons using manual salts is discouraged is to prevent things like this.

So a solution could be:

let FOSUserBundle use password_hash to create the hash without manually specifying a salt.

extract the salt from the result string and pad it with 0 to a length of 32 chars

pass this salt to the client

Can anyone confirm, that this a real solution and not just some coincidence ?

This is not a good solution. The only good way is to make sure password hashing is implemented the right way so you don't have to generate the salt more than once.


Let client provide any salt. Or server gives a random salt it has never used. Treat the hash as the raw password. Re-hash the hashed password and rest stuff.