将密码哈希算法从md5升级到bcrypt

9

这个问题之前已经讨论过,但似乎没有结论。

理想情况下,不希望在数据库中维护状态(升级/未升级)等信息,所以我想到了以下方案:

对MD5加密后的密码进行bcrypt处理,并使用“用户名+其他内容”作为盐值。

  1. 这个方案有意义吗?
  2. 一般来说,将用户名作为盐值的一部分是一个好主意吗?我在某处读到每个哈希都添加不同的盐值可以增强安全性。这种做法正确吗(尤其是在bcrypt的情况下)?

请解释一下为什么要点踩。 - merlinbeard
4
在你发帖之前,建议将此内容发布到 [security.se] 上以得到更好的适应性,但请务必在发布前查看其帮助中心。 - user1864610
请查看 password_hash() 函数 http://php.net/manual/zh/function.password-hash.php - timgavin
@user3714828 password_hash() 会自动生成盐值,所以您不必担心用户名的问题。 - timgavin
@user3714828 是的,添加额外熵是使加盐有用的原因。这意味着未来的黑客在尝试入侵时必须处理所有这些额外的熵。 - Mihai Stancu
显示剩余2条评论
1个回答

9

毫无疑问,转换到更安全的哈希算法是一个好主意。你可以使用一个名为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() 函数会处理这个问题。由于必须为每个盐构建彩虹表,攻击者需要为每个密码构建彩虹表。有关更多信息,请参阅我的安全密码存储教程。


这很有用。谢谢! - merlinbeard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接