2011-04-07 78 views
3

阅读this excellent answer约密码哈希,不知道如何实现它:如何正确实现hash_hmac?

The Wicked Flea写道:

生成每个用户的随机数;仅这一件就击败了彩虹桌。这是一个随机数,它取决于范围,扩展了产生的散列数。

那么除了用户的密码在我的数据库中存储唯一的令牌吗?

的示例代码在原岗位:

function hash_password($password, $nonce) { 
    global $site_key; 
    return hash_hmac('sha512', $password . $nonce, $site_key); 
} 

我如何可以验证此代码密码?让我来解释:

当用户提交自己的密码,我需要生成它的散列,以检查其中的电子邮件地址哈希密码匹配现有的数据库行。当我对用户'$nonce一无所知时,我如何选择这一行?我错过了什么吗?也许我需要通过只有他的电子邮件地址选择用户,然后再验证密码散列?

顺便说一句,你推荐这种哈希方法?

+0

您不需要选择使用密码作为选择标准的用户。只需根据电子邮件地址或登录等独特特征选择用户,然后再检查密码。也见有关哈希想法的一个相关问题(免责声明:我就此回答):http://stackoverflow.com/questions/3787346/email-address-as-password-salt/3787414#3787414 – Archimedix 2011-04-07 10:27:38

+1

顺便说一句,通过用户名只选择还有一个好处,你可以显示“用户不存在”或“密码无效”,这取决于错误,这极大地增加了你网站的可用性。有时候,无论出于何种原因,你都必须使用不同的用户名,并且经过很长时间,你可能会尝试使用旧的密码和大量的密码,因为它只是说“登录失败”。有了“用户不存在”的错误,这将不是必需的 – ThiefMaster 2011-04-07 10:33:23

+0

@Archimedix感谢您的回复。顺便说一句,抱歉,但我看不出将系统范围的盐添加到明文密码或密钥之间的区别。你能说明一下吗? – fabrik 2011-04-07 10:48:37

回答

3

我想你已经明白了这个想法。在一般的UNIX风格的盐腌密码中应用了相同的概念 - 以明文形式存储salt并使用密码进行检索,然后使用salt和提供的密码生成与存储值相比较的新散列。

它是由你来考虑无论您信任你的数据库服务器(以及它的连接)使用由数据库支持的哈希算法,让DB做数学题:

SELECT * FROM users WHERE email = 'email' AND password = SHA1(CONCAT('cleartextpass',nonce)); 

或者,您可以在检索所有匹配的电子邮件后,在代码中进行数学运算。

编辑:上区分丢失的用户密码无效的ThiefMaster评论是经典的安全漏洞,允许攻击者获得的有效用户名列表,并集中在打破自己的密码,而不是捕鱼那黑暗。我强烈建议它。

+0

你能解释一下你的答案吗?这并不完全清楚'nonce'来自哪个查询。基本上你的解决方案对我来说更好,因为它只能通过数据库查询来完成。 – fabrik 2011-04-07 10:52:18

+0

在SQL查询中,_nonce_是表列的名称(注意,它未被引用)。 这意味着CONCAT()采用明文密码并附加在字段_nonce_ – Laas 2011-04-07 11:01:25

+0

中,并且我也可以在SQL和PHP中生成SHA1密钥,对吗?我可以将这个* nonce *字段用于其他目的吗?忘记密码令牌等?或者这会是一个安全缺陷? – fabrik 2011-04-07 11:07:55