Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the password_needs_rehash function in PHP 5.5

I have a set of passwords in my database that I had earlier hashed using sha512 and now that I have upgraded my server to PHP 5.5, I would like to use the bcrypt password hashing. So my idea is to have the user's login and then call this password_needs_rehash function described here to check the password and then update the password hash in database:

http://php.net/manual/en/function.password-needs-rehash.php

I'm not sure how to use this function though,there are no examples listed here and it doesn't really clarify what the options array is for. Do I just need to call the password_needs_rehash function like this:

if (password_needs_rehash ($current_hash, PASSWORD_BCRYPT)) {
  // update the password using password_hash
}
like image 689
Ashesh Avatar asked Sep 27 '13 15:09

Ashesh


3 Answers

Yes, that's the general idea.

If the password needs to be rehashed, then you just call password_hash() to rehash it. And, of course, save the new hash in your database.

if (password_needs_rehash ($current_hash, PASSWORD_BCRYPT)) {
  // update the password using password_hash
  $new_hash = password_hash($cleartext_password, PASSWORD_BCRYPT)
  // update the database
  ...
}
like image 171
Michael Hampton Avatar answered Sep 23 '22 00:09

Michael Hampton


Yes, that's correct. The only option you may want to set is "cost", denoting how much work it takes to generate the hash (and therefore how hard it is to crack). Cost defaults to 10 for bcrypt but can be increased to make hashes harder to crack. So you might set "cost" to 11 here, and use the same value when generating new hashes. The benefit of that is that you could later change it to 12, and it would upgrade existing hashes that were already on bcrypt but only with a cost of 11.

like image 33
Nick Avatar answered Sep 26 '22 00:09

Nick


Try this:

$passwordFromDatabase = "A1D292F556AA661B720847487960860F17086A0BD11A4320368E9447FF7139DE089AA88B6159420814F10194F1AA55A3379FB80EA26BA6397BA75CEC811B241A"; // sha512 hash of "somepassword"
$passwordFromForm = $_POST['password']; // $_POST['password'] == "somepassword"

if(password_needs_rehash($passwordFromDatabase, PASSWORD_BCRYPT, ["cost" => 12]) && hash("sha512", $passwordFromForm) === $passwordFromDatabase){
    // generate new password hash
    $newPasswordHash = password_hash($passwordFromForm, PASSWORD_BCRYPT, ["cost" => 12]);
    // update hash from database - replace old hash $passwordFromDatabase with new hash $newPasswordHash
    // after update login user
    if(password_verify($passwordFromForm, $newPasswordHash)){
        // user has logged in successful and hash was updated
        // redirect to user area
    }else{
        // ups something went wrong Exception
    }
}else{
    if(password_verify($passwordFromForm, $passwordFromDatabase)){
        // user password hash from database is already BCRYPTed no need to rehash
        // user has logged in successfully
        // redirect to user area
    }else{
        // wrong password
        // no access granted - stay where you are
    }
}

Ps. If you think about setting your own salt... please don't do that. You won't do it better than a native password_hash(...) php function. Just set the cost which provides balance between check speed and security against brute forcing. If you leave options blank, the cost will by default get set to 10.

like image 42
DevWL Avatar answered Sep 24 '22 00:09

DevWL