这个问题之前已经讨论过,但似乎没有结论。
理想情况下,不希望在数据库中维护状态(升级/未升级)等信息,所以我想到了以下方案:
对MD5加密后的密码进行bcrypt处理,并使用“用户名+其他内容”作为盐值。
- 这个方案有意义吗?
- 一般来说,将用户名作为盐值的一部分是一个好主意吗?我在某处读到每个哈希都添加不同的盐值可以增强安全性。这种做法正确吗(尤其是在bcrypt的情况下)?
毫无疑问,转换到更安全的哈希算法是一个好主意。你可以使用一个名为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);
首先进行验证检查双哈希,然后相应地验证密码。
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() 函数会处理这个问题。由于必须为每个盐构建彩虹表,攻击者需要为每个密码构建彩虹表。有关更多信息,请参阅我的安全密码存储教程。
password_hash()
函数 http://php.net/manual/zh/function.password-hash.php - timgavinpassword_hash()
会自动生成盐值,所以您不必担心用户名的问题。 - timgavin