我对this question上的两个最佳答案的建议有疑问。
在他们的答案的最后一部分,他们说加密密码哈希比使用硬编码的胡椒更好的可维护性(万一哈希泄漏,您可以旋转密钥)。
这是他们在说什么的伪代码吗?
$key = 'random_key_stored_elsewhere';
$hash = bcrypt($password);
$encrypted = encrypt($hash, $key);
// store $encrypted to DB
现在要检查登录尝试:
if (bcrypt($user_input) == decrypt($encrypted, $key))
{
// proceed login...
}
说哈希泄漏,现在我们需要更改密钥并重新加密哈希:
$decrypted_data = decrypt($encrypted, $key)
$new_key = 'new_random_key_stored_elsewhere';
$encrypted = encrypt($decrypted_data, $new_key);
// store $encrypted to DB
是吗?如果是,那么如果使用相同的过程来检查登录尝试,那么在散列泄漏的情况下旋转密钥如何使可能被破解的密码无效?例如,
if (bcrypt($user_input) == decrypt($encrypted, $new_key))
{
// proceed login...
}
旋转键会毫无用处,还是我错过了什么?
答案 0 :(得分:1)
您假设当密钥丢失时,密码哈希也将丢失,这确实经常是这种情况。在这种情况下,无论您是对密码哈希进行加密还是使用胡椒粉,都无法得到保护。
虽然还有其他情况。也许您的源代码泄漏,有人不小心签入了版本控制系统中的密钥,或者某个开发人员的机器有后门。一旦发现了此类漏洞,就可以在服务器上的密钥进行交换,然后再攻击包含哈希的数据库。使用Pepper时,您必须重新设置所有密码,然后将其告知用户。
也许攻击者获得了密码哈希(SQL注入,备份),现在尝试攻击您的服务器以获取密钥。如果您及时发现它,则可以交换密钥,并且泄漏的哈希值一文不值。您将获得从密码泄漏到密钥泄漏之间的时间。
顺便说一句,您的描述几乎是正确的,要验证密码,您必须先解密哈希,然后才能使用BCrypt验证(无法进行比较)。
if (bcrypt_verify($user_input, decrypt($encrypted, $key)))