上周我读了很多关于密码散列的文章,Blowfish似乎是目前最好的散列算法之一-但这不是这个问题的主题!
The 72 character limit
BooFISH只考虑输入密码中的前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正在使用blowfish(又名bcrypt)来存储他们的密码(https://shouldichangemypassword.com/twitter-hacked.php),你猜怎么着:把你的twitter密码改成一个超过72个字符的长密码,你只需输入前72个字符就可以登录到你的账户.
Blowfish and Pepper
关于"胡乱输入"密码有很多不同的观点.有些人说这是不必要的,因为您必须假设秘密的胡椒字符串也是已知的/发布的,这样它就不会增强散列.我有一个单独的数据库服务器,所以很可能只有数据库泄露,而不是常量的胡椒.
在这种情况下(pepper not Leak),基于字典的攻击会变得更加困难(如果不正确,请纠正我).如果你的胡椒串也泄漏了:没那么糟糕——你仍然有盐,它就像没有胡椒的土豆条一样受到保护.
因此,我认为加密密码至少不是一个坏 Select .
Suggestion
我建议对超过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));
?>
这是基于this question:password_verify
返回false
.
The Question
什么是更安全的方式?首先获取SHA-256散列(返回64个字符),还是只考虑密码的前72个字符?
赞成的意见
- 用户仅输入前72个字符无法登录
- 您可以在不超过字符限制的情况下添加胡椒
- HASH_HMAC的输出可能比密码本身具有更大的熵
- 密码由两个不同的函数散列
欺骗
- 只有64个字符用于构建河豚散列
Edit 1:这个问题只涉及Blowfish/bcrypt的PHP集成.感谢您的 comments !