上周,我读了很多有关密码哈希的文章,而Blowfish似乎是目前最好的哈希算法之一(但其中之一),但这不是这个问题的主题!
最多72个字符
河豚只考虑输入的密码中的前72个字符:
<?php
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$hash = password_hash($password, PASSWORD_BCRYPT);
var_dump($password);
$input = substr($password, 0, 72);
var_dump($input);
var_dump(password_verify($input, $hash));
?>
输出为:
string(119) "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)"
string(72) "Wow. This is a super secret and super, super long password. Let's add so"
bool(true)
如您所见,只有前72个字符很重要。Twitter正在使用河豚(又名bcrypt)存储其密码(https://shouldichangemypassword.com/twitter-hacked.php)并猜测:将您的Twitter密码更改为包含72个字符以上的长密码,您可以通过以下方式登录到您的帐户仅输入前72个字符。
河豚和胡椒
关于“ peppering”密码有很多不同的意见。有人说这是不必要的,因为您必须假定秘密胡椒字符串也已知道/已发布,因此它不会增强哈希值。我有一个单独的数据库服务器,因此很有可能只有数据库泄漏了,而不是不断泄漏。
在这种情况下(胡椒未泄漏),您将很难基于字典进行攻击(如果这不正确,请纠正我)。如果您的胡椒粉串也泄漏了:还算不错-您仍然有盐分,并且像没有胡椒粉的土豆泥一样受到了很好的保护。
因此,我认为加密码至少不是坏选择。
建议
我的建议是使用Blowfish哈希来获取长度超过72个字符(和胡椒)的密码:
<?php
$pepper = "foIwUVmkKGrGucNJMOkxkvcQ79iPNzP5OKlbIdGPCMTjJcDYnR";
// Generate Hash
$password = "Wow. This is a super secret and super, super long password. Let's add some special ch4r4ct3rs a#d everything is fine :)";
$password_peppered = hash_hmac('sha256', $password, $pepper);
$hash = password_hash($password_peppered, PASSWORD_BCRYPT);
// Check
$input = substr($password, 0, 72);
$input_peppered = hash_hmac('sha256', $input, $pepper);
var_dump(password_verify($input_peppered, $hash));
?>
这是基于以下问题:password_verify
返回false
。
问题
什么是更安全的方法?首先获取SHA-256哈希(返回64个字符)还是仅考虑密码的前72个字符?
优点
- 用户无法通过仅输入前72个字符来登录
- 您可以在不超过字符数限制的情况下添加胡椒
- hash_hmac的输出可能比密码本身具有更多的熵。
- 密码由两个不同的函数进行哈希处理
缺点
- 仅使用64个字符来构建河豚哈希
编辑1:这个问题只解决了blowfish / bcrypt的PHP集成。感谢您的评论!