Reputation: 1964
I have a PHP application that has a somewhat decent userbase. Now unfortunately, it has been using sha1($password . $salt) all these years and I really want to ditch that in favor of bcrypt. I have found some nice ways of getting a Blowfish hash, but I am still unsure about the conversion approach that I should use. Here are my options:
Every time a user logs in, I check if the hash starts with $2. If not, I assume it is sha1, take the password entered by the user, get the bcrypt hash for it and replace the old hash in the database.
I replace my auth class to do this:
$hash = password_hash("rasmuslerdorf", sha1($password . $salt));
That way, conversion is quicker.
But honestly, I don't really like either of the options. Both suggest that I still keep a legacy check in the codebase which I want to get rid of.
Any suggestions which of the above two are better from a coding standards point of view? Or does someone have a better solution?
Upvotes: 6
Views: 2697
Reputation: 1
Add a new DB col, let's say [passNeedSystemUpdate], your default value will be 1. 1 = true or yes and 0 = na.
Process the user login as normal until you get to the end then run a check to see if the passNeedsSystemUpdate = 1. If the password needs updating then we take the users input from the password field and update the new password along with passNeedSystemUpdate which will now be 0.
NOTE: If in the event that your DB is compromised or has been, then users will have no other option but to create a completely new password. The above is just a bit of logic to use if you're changing your current encryption from sha256 to bycrypt or something else.
Upvotes: 0
Reputation: 24071
Every password-storing-system must have the option to switch to a better hash algorithm, your problem is not a one-time migration problem as you may think. Good password hash algorithms like BCrypt have a cost factor, from time to time you have to increase this cost factor (because of faster hardware), then you need the same procedure as you need for the migration.
Your Option1 is a convenient approach, as long as the hashes are not terrible unsafe (unsalted or very weak algorithm). In PHP's new password API, you will even have a function password_needs_rehash() to determine whether an update is necessary.
I would recommend to let the fallback stay in the code, you will spare your customers the hassle of confront their users with an invalid password. As a user i don't like emails that demand to click a link and reenter my password, users are taught to ignore such email because of phishing. As said before, such fallbacks in the code are not bad, it is a necessary step to get a safe password handling.
Upvotes: 2