I am keen to migrate my code to the new password_* functions provided natively by PHP.
The existing hashes in the database have been generated as follows:
hash ('sha512', '<A constant defined earlier>' . $email . $password);
I'd like to move these to be hashes created by the now-recommended:
password_hash ($password, PASSWORD_DEFAULT);
Obviously, when a user logs in, I can take the opportunity to create the new hash from the password they just provided, and save that in the database.
However, I'd like to avoid having to have two fields in the database, namely one for the deprecated hash and one for the modern password_hash one. Instead, I'd rather just replace the old ones as each user logs in.
Therefore, is it possible to keep a single database field, and have the userland code determine whether the hash is old, i.e. determine which check to use?
(I'm assuming that the hash('sha512') hashes cannot be automatically upgraded to crypt() ones?)
Hashes created with password_hash
will have a very distinctive $2y$
string at the beginning (or similar $..$
, as long as you're operating with the current default Blowfish cypher), while SHA256 will simply be all hex values. Therefore, you can simply test whether a value is a legacy hash value or a password_hash
value:
function isLegacyHash($hash) {
return !preg_match('/^\$\w{2}\$/', $hash);
}
Using this, you can keep both types of hashes in a single field and upgrade them when the user logs in. Alternatively, you could simply set a flag in a column like hash_version
.