8

My database stores the bcrypt passwords which means that the salt should be stored with in the password field. I don't want to make a separate field to store the salt by itself when it is not necessary. However when I want to compare passwords that the user sends to me to the passwords stored in the database, I need to hash the incoming password with the same salt. Question: what part of the stored hash is the salt? I think I could just return the salt using simple substr().

// password stored in database.
$user->password_hash = password_hash($password, PASSWORD_BCRYPT, array('cost' => 13));


// password from form being compared to form password

$form_password_hash = password_hash($data['form-password'], PASSWORD_BCRYPT, array('cost' => 13));

if($user->getPasswordHash() == $form_password_hash)
{
    $user->setPassword($data['new-password']);
    return new Response("Your password has been changed");
}
1615903
  • 32,635
  • 12
  • 70
  • 99
Dr.Knowitall
  • 10,080
  • 23
  • 82
  • 133
  • No; bcrypt does this for you. – SLaks Jun 26 '13 at 22:13
  • Every bcrypt library I've used just deals with the whole string, you don't need to pass the salt in seperately. Surely that's an option? – joshuahealy Jun 26 '13 at 22:14
  • Ya I know bcrypt does this for you. The problem that I'm having is that I need to use the same salt that hashed the database password. The bcrypt function automatically picks a "random" salt to use, but I can't use any random salt. – Dr.Knowitall Jun 26 '13 at 22:14
  • And if all else fails... Desalination – joshuahealy Jun 26 '13 at 22:14
  • The encryption part might use a random salt but the comparison function should take the hash and the string you want to compare it with. – joshuahealy Jun 26 '13 at 22:17
  • 3
    When you say "bcrypt is generating a new salt" I hear "I am doing this wrong". Post your code. – Sammitch Jun 26 '13 at 22:17
  • 1
    Take a look at this answer, which has several ways of using bcrypt in php depending on the version you are runnning: http://stackoverflow.com/a/6337021/1248861 – joshuahealy Jun 26 '13 at 22:22
  • 1
    @Mr.Student `password_verify` does that for you. It does not generate a new salt, it uses the salt that's included with the hash you pass in. – CodesInChaos Jun 27 '13 at 06:06

2 Answers2

13

Salt is the first 22 characters after the third $ in the hash:

$2y$13$<this is the salt, 22 chars><this is the password hash>

But you should not manually extract the salt to verify the password - use the password_verify function. It takes the password the user entered as the first argument, and the complete hash as the second argument, and handles the salt correctly.

1615903
  • 32,635
  • 12
  • 70
  • 99
  • 2
    well it is useful for debugging when you want to recreate the hash yourself using password_hash(); – My1 Dec 15 '15 at 14:25
10

You need to use the password_verify function. This function will parse the hashed password string to find the salt and perform the calculation.

if (password_verify($data['form-password'], $user->getPasswordHash())) {
    echo 'Password is correct';
}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
joshuahealy
  • 3,529
  • 22
  • 29