当然,切换到更安全的哈希算法是个好主意。有一个函数 password_hash() 可用于创建 BCrypt 哈希:
// 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);
根据您的回答,我猜您使用了未加盐的 MD5 值,因此双散列在这里可能是一个很好的解决方案。只需将 MD5 哈希传递给 password_hash() 函数,它就会自行生成一个安全的盐。
// Migrating the old MD5 hashes to MD5-BCrypt
$hashToStoreInDb = password_hash($existingMd5Hash, PASSWORD_DEFAULT);
先验证check for a double hash,再验证密码。
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)
}
存储的哈希值可以通过前导 $ 或单独的 db 字段来识别,例如 BCrypt 哈希值总是以 $ 字符开头,而 MD5 哈希值则不是。
盐应该不来自其他参数,并且每个密码应该是唯一的。 password_hash() 函数会处理这个问题。由于必须为每个盐构建一个彩虹表,因此攻击者必须为每个密码构建一个彩虹表。有关更多信息,您可以查看我关于 secure password storing 的教程。