上周我读了很多关于密码哈希和 Blowfish 的文章,它们似乎是目前最好的哈希算法之一——但这不是这个问题的主题!
Blowfish 只考虑输入密码的前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个字符就可以登录你的账户。
关于“胡乱设置”密码有很多不同的观点。有些人说这是没有必要的,因为你必须假设秘密的胡椒弦也是已知的/已发表的,所以它不会增强散列。我有一个单独的数据库服务器,所以很有可能只有数据库泄漏,而不是不断胡椒。
在这种情况下(胡椒未泄漏) ,您使得基于字典的攻击更加困难(如果这是不正确的,请纠正我)。如果你的辣椒串也泄露了: 没那么糟糕——你还有盐,它就像没有辣椒的土豆泥一样受到了很好的保护。
所以我认为在密码上乱加密码至少是个不错的选择。
我建议使用 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个字符?
编辑1: 这个问题只讨论了河豚/bcrypt 的 PHP 集成。感谢评论!