【发布时间】:2011-07-31 13:49:19
【问题描述】:
阅读this excellent answer关于密码哈希并想知道如何实现它:
The Wicked Flea 写道:
为每个用户生成一个随机数;仅此一项就击败了彩虹桌。这是一个随机数,会根据范围扩展产生的哈希值的数量。
那么除了用户密码之外,我的数据库中还要存储一个唯一的令牌?
原帖中的示例代码:
function hash_password($password, $nonce) {
global $site_key;
return hash_hmac('sha512', $password . $nonce, $site_key);
}
如何使用此代码验证密码?让我解释一下:
当用户提交他的密码时,我需要生成它的哈希来检查电子邮件地址 和 哈希密码匹配的现有数据库行。当我对用户的$nonce 一无所知时,如何选择此行?我错过了什么吗?也许我只需要通过他的电子邮件地址选择用户,然后稍后验证密码哈希?
顺便说一句,你推荐这种散列方法吗?
【问题讨论】:
-
您不需要使用密码作为选择标准来选择用户。只需根据电子邮件地址或登录名等独特特征选择用户,然后检查密码。另请参阅有关一些散列想法的相关问题(免责声明:我对此进行了回答):stackoverflow.com/questions/3787346/…
-
顺便说一句,仅按用户名选择还有一个优点是您可以根据错误显示“用户不存在”或“密码无效”,这极大地增加了您的可用性网站。有时您出于某种原因不得不使用不同的用户名,并且在很长一段时间后您可能会尝试使用旧的用户名和大量密码,因为它只会显示“登录失败”。如果出现“用户不存在”错误,则无需这样做
-
@Archimedix 感谢您的回复。顺便说一句,对不起,但我看不出将系统范围的盐添加到明文密码或密钥之间的区别。你能解释一下吗?
-
无论如何我都不是加密专家,但看到你的盐是你认为你的密钥来加密用户的密码(即用户的秘密),我只会使用HMAC 密钥中的盐并将密码放入消息部分。这样,用户就不会影响 HMAC 密钥来进行差异攻击。
-
是的,可用性增强“用户不存在”是一个安全漏洞,正如 Laas 所说的那样,因为它使攻击者能够编写有效用户帐户的列表。在这里,您可以将安全性较差的网站与也许安全性不太差的网站区分开来。然而,基于时间的攻击仍然可以用来确定哪些帐户可能是有效的,但是信心有限——对于一个拥有许多活跃用户的网站,很难说不同的加载时间是由检索不存在的用户还是由不存在的用户引起的。密码错误。