Rehashing passwords without asking all users to ch

2019-08-12 02:30发布

A former developer used the PHP hash() function with the SHA256 algorithm to store password hashes. To improve the security of the system, I'd like to start using crypt() with the Blowfish algorithm (unfortunately we don't have PHP 5.5 and thus password_hash() is not available).

Since SHA256 is a non-reversible hashing algorithm, is there a way to start using crypt() with the salted passwords without asking everyone to reset their password?

7条回答
唯我独甜
2楼-- · 2019-08-12 02:48

Id say use a marker field to annotate which users have been previously hashed, then crypt the existing hash. For anyone with a true in the marker field when authenticating it becomes a 2 step process, hash the password then crypt it for a match check.

Whenever they update their password you would set the marker field to false. i.e. phase in and just crypt for a match check.

查看更多
唯我独甜
3楼-- · 2019-08-12 02:53

Another approach you may want to consider is hash chaining: since you can't reverse SHA256, just define your new hash function as crypt(sha256($passwd)). Since you presumably already have sha256($passwd) on file for all your passwords, it's possible to crypt() each one of them with an appropriate salt to update your existing hashes (without having to wait for the user to log in).

查看更多
神经病院院长
4楼-- · 2019-08-12 02:55

Yes, what you will need to do is add an extra column that stores the crypt() output. When a user logs in, and their password successfully hash()es to what you have in the database, you can now crypt() that password, and remove the old hash from the database.

This only works when users log-in, so you will have a period of time where some users are using the old system, and some users are using the new one.

查看更多
Juvenile、少年°
5楼-- · 2019-08-12 02:57

Here's a possible solution:

Add a column to the user table to indicate which hashing method has been used on the user's password. At login time you'll know the user's password since he's just entered it, so once the current hash has been passed, crate a new has from the password and update the flag column

This assumes that you're passing free text passwords across the internet which you shouldn't do unless you're using SSL.

Alternatively, if you're hashing the password on the client before sending it, update the client software to handle two hashing algorithms and send both. Use your flag to identify which to check.

In both cases once all (or the majority of) your users have switched, deleted the old hashes and force the issue for the remaining users.

查看更多
贪生不怕死
6楼-- · 2019-08-12 02:58

You should use the compatibility library then. It will make it easier for you when you move to 5.5.

Re-hashing without asking the user for the password... well, you can wait until the next time users log in, and then use the password extension's password_verify() function. If it fails then you can fall back on the old SHA256 hash. If the SHA256 hash matches then you can rehash the password using password_hash() and save it in the old hash's place:

if (password_verify($password, $hash)) {
    // Matches...
} elseif (hash('sha256', $password) == $hash) {
    // Matches...
    $newHash = password_hash($password);
    // Save $newHash in the old hash's place
} else {
    die('Invalid password...');
}

It is technically possible to crack a lot of the hashes, but there are too many problems with that (you would not get all of them, it is most likely not feasible, it may not even be legal, etc.).

查看更多
别忘想泡老子
7楼-- · 2019-08-12 02:58

I'm assuming you never stored the clear-text user account passwords, as this would be truly an awful thing to do. SO therefore you no longer have the data that you need to create the new password digests.

I'm thinking you're going to need everyone to update their passwords.

查看更多
登录 后发表回答