Upgrade password hash from md5 to bcrypt
Surely it is a good idea to switch to a more secure hash algorithm. There is a function password_hash() you can use for creating a BCrypt hash:
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);
From your answer i guess that you used an unsalted MD5 value, so double hashing can be a good solution here. Just pass the MD5 hash to the password_hash() function, it will generate a safe salt on its own.
// Migrating the old MD5 hashes to MD5-BCrypt
$hashToStoreInDb = password_hash($existingMd5Hash, PASSWORD_DEFAULT);
For verification first check for a double hash, and then verify the password accordingly.
if (checkIfDoubleHash($existingHashFromDb))
{
$isPasswordCorrect = password_verify(MD5($password), $existingHashFromDb);
// Update database with pure BCrypt hash
if ($isPasswordCorrect)
$hashToStoreInDb = password_hash($password, PASSWORD_DEFAULT);
}
else
{
$isPasswordCorrect = password_verify($password, $existingHashFromDb)
}
The stored hashes can be recognized by the leading $ or by a separate db field, a BCrypt hash for example always starts with a $ character, an MD5 hash does not.
A salt should not be derrived from other parameters and it should be unique per password. The password_hash() function will take care of this. Since a rainbowtable must be built fore each salt, an attacker would have to build a rainbowtable for each password. For more information you can have a look at my tutorial about secure password storing.
Comments
-
merlinbeard almost 2 years
Its been discussed here before, but there seems to be no conclusion.
Ideally, don't want to maintain state (upgraded/not upgraded) in the database etc. so, here is what I'm thinking:
bcrypt the MD5'd password, and use "username + something else" as a salt.
- Does this scheme make any sense?
- Also, in general is it a good idea to use the username as a part of the salt? I read somewhere that adding a different salt to each hash makes it more secure. Is that correct (especially in context of bcrypt)?
-
merlinbeard over 9 yearsThis is useful. Thank you!