thilakan Posted August 10, 2014 Share Posted August 10, 2014 When to use password_needs_rehash Workflow for account registration. 1. The user creates an account. 2. Their password is hashed password_hash($password, PASSWORD_DEFAULT) and stored in the database. 3. When the user attempts to login, the hash (password_verify ) of the password they entered is checked against the hash of their real password (retrieved from the database). 4. If the hashes match, the user is granted access. If not, the user is told they entered invalid login credentials. My question is 1. When should I call password_needs_rehash? 2. Do I really need to use it? Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted August 10, 2014 Share Posted August 10, 2014 (edited) I assume you only need to call password_needs_rehash in the event PHP modifies the default hashing algorithm or you choose to use a stronger algorithm (when they become available) . For example the password hashes stored in your the database would of been generated using the old algorithm. Meaning when you go to compare the hashes they will no longer match, even though the user entered the correct password. password_needs_rehash will return true if the old hash (stored in the database) is not compatible with the new algorithm, when this happens you can safely rehash the users password to use the new algorithm and update your users password hash stored in the database so it is now compatible with the new algorithm. Edited August 10, 2014 by Ch0cu3r Quote Link to comment Share on other sites More sharing options...
thilakan Posted August 10, 2014 Author Share Posted August 10, 2014 (edited) Thank you for your answer. Now I am going to place the password_needs_rehash code in the login file. My code looks like this: if (password_verify('password', $hash)) { echo 'Password is valid!'; // CHECK TO SEE PASSWORD NEED REHASH if (password_needs_rehash($hash, $algorithm, $options)) { $hash = password_hash($password, $algorithm, $options); /* Store new hash in db */ } } else { echo 'Invalid password.'; }?> Is this the right method ? Here, am I supposed to rehash the old password stored in the database or should I ask the user to enter a new password? Edited August 10, 2014 by thilakan Quote Link to comment Share on other sites More sharing options...
Solution Jacques1 Posted August 10, 2014 Solution Share Posted August 10, 2014 Ch0cu3r's assumption is wrong. First of all, relying on the default algorithm is a bad idea, because you lose one of the key features of modern password hash algorithms: the ability to tweak the computational cost for the specific server hardware and the specific use case. A good dedicated server has much more power than some cheap shared host, so it would be silly to use the same weak settings in both cases and make life easier for attackers. An admin account is much more important than a regular user account, so again it would be silly the use some standard setting. And of course hardware generally becomes better over time. There simply is no one-size-fits-all configuration. Pick a specific algorithm and a specific cost factor. The only algorithm available at this time is bcrypt, and the right cost factor can be determined by choosing the desired duration of the hash calculation and increasing the cost factor until you get this duration on your current server. Revise the settings when the hardware changes. Now that you understand the importance of adjusting the algorithm, it's should also be obvious why rehashing is needed. Whenever you change the cost factor, you should upgrade existing hashes. This happens in the log-in procedure after(!) you've checked the password: <?php // Those settings should be in some external configuration file define('PASSWORD_HASH_ALGORITHM', PASSWORD_BCRYPT); define('PASSWORD_HASH_COST', 14); // log-in ... if (password_verify($_POST['password'], $stored_password_hash)) { // does the current hash need an update? if (password_needs_rehash($stored_password_hash, PASSWORD_HASH_ALGORITHM, array('cost' => PASSWORD_HASH_COST))) { $updated_password_hash = password_hash($_POST['password'], PASSWORD_HASH_ALGORITHM, array('cost' => PASSWORD_HASH_COST)); // replace the current hash with $updated_password_hash } ... } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.