2014-09-30 153 views
6

其前面已经讨论过,但似乎没有任何结论。将密码哈希从md5升级到bcrypt

理想的情况下,不希望维护状态(升级/不升级)的数据库等,所以,这里是我在想什么:

bcrypt的MD5'd密码,并使用“用户名+别的东西“作为盐。

  1. 这个方案有什么意义吗?
  2. 此外,通常使用用户名作为盐的一部分是一个好主意?我在某处读到,为每个散列添加不同的盐使其更安全。这是否正确(特别是在bcrypt的情况下)?
+0

请解释downvote – merlinbeard 2014-09-30 03:57:28

+4

这会更适合[security.se],但请在发布之前查看他们的帮助中心。 – 2014-09-30 03:57:48

+0

查看'password_hash()'http://php.net/manual/en/function.password-hash.php – timgavin 2014-09-30 03:59:20

回答

6

当然,切换到更安全的散列算法是一个好主意。还有一个功能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()函数,它将自行生成一个安全的salt。

// 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) 
} 

存储的哈希值可以由领导$或单独的数据库字段来识别,例如BCrypt哈希总是以$字符开头,MD5哈希没有。

盐应该而不是被从其他参数诠释,它应该是唯一的每个密码。 password_hash()函数将处理这个问题。由于必须在每个盐之前建立彩虹色表,攻击者必须为每个密码创建一个彩虹表。欲了解更多信息,你可以看看我的教程secure password storing

+0

这很有用。谢谢! – merlinbeard 2014-09-30 09:04:13