Php 如何正确地实现hash_hmac?

Php 如何正确地实现hash_hmac?,php,hash,passwords,hmac,Php,Hash,Passwords,Hmac,阅读有关密码散列的内容并想知道如何实现它: 写道: 为每个用户生成一个nonce;仅此一项就击败了彩虹桌。这是一个随机数,根据范围的不同,它会扩展结果散列的数量 那么在用户密码旁边,在我的数据库中存储一个唯一的令牌 原始帖子中的示例代码: function hash_password($password, $nonce) { global $site_key; return hash_hmac('sha512', $password . $nonce, $site_key); } 如何

阅读有关密码散列的内容并想知道如何实现它:

写道:

为每个用户生成一个nonce;仅此一项就击败了彩虹桌。这是一个随机数,根据范围的不同,它会扩展结果散列的数量

那么在用户密码旁边,在我的数据库中存储一个唯一的令牌

原始帖子中的示例代码:

function hash_password($password, $nonce) {
  global $site_key;
  return hash_hmac('sha512', $password . $nonce, $site_key);
}
如何使用此代码验证密码?让我解释一下:

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


顺便说一句,你推荐这种散列方法吗?

我想你已经确定了这个想法。在通用UNIX风格的salt密码中也应用了相同的概念—使用密码以明文形式存储salt,并通过用户名检索它,然后使用salt和提供的密码生成新的散列以与存储的值进行比较

<> P>由你考虑你信任你的DB服务器(和它的连接)使用一个由DB支持的哈希算法,让DB做数学:

SELECT * FROM users WHERE email = 'email' AND password = SHA1(CONCAT('cleartextpass',nonce));
或者,你可以在检索所有匹配的电子邮件后在代码中进行计算


编辑:ThiefMaster关于区分丢失用户和无效密码的评论是一个典型的安全漏洞,它允许攻击者获取有效用户名列表,并集中精力破解密码,而不是在黑暗中钓鱼。我强烈建议您不要这样做。

您不需要使用密码作为选择标准来选择用户。只需根据电子邮件地址或登录名等唯一特征选择用户,然后检查密码。另请参阅一些散列想法的相关问题(免责声明:我已就此回答):顺便说一句,仅按用户名选择也具有优势,您可以根据错误显示“用户不存在”或“密码无效”,这极大地提高了网站的可用性。有时,无论出于何种原因,您都必须使用不同的用户名,经过很长一段时间后,您可能会尝试使用旧用户名和大量密码,因为它只显示“登录失败”。如果出现“用户不存在”错误,则不会出现此错误necessary@Archimedix谢谢你的回复。顺便说一句,很抱歉,我看不出将系统范围的salt添加到明文密码或密钥之间的区别。你能摆脱它吗?我并不是什么秘密专家,但看到你的盐是你认为你的秘密密钥来加密用户的密码(对用户来说是秘密的),我只会使用HMAC密钥中的盐并将密码放入消息部分。这样,用户就不会影响HMAC密钥来运行差异攻击。是的,可用性增强“用户不存在”是一个安全缺陷,正如Laas正确地说的那样,它使攻击者能够创建一个有效用户帐户列表。在这里,您可以区分安全性差的站点和安全性可能不太差的站点。然而,基于时间的攻击仍然可以用来确定哪些帐户是有效的,但是信心有限-对于一个有许多活跃用户的站点,很难说不同的加载时间是由检索不存在的用户还是错误的密码引起的。你能解释一下你的答案吗?在您的查询中,
nonce
从何而来并不完全清楚。基本上,您的解决方案对我来说更合适,因为它只能通过数据库查询完成。在SQL查询中,nonce是表列的名称(注意,它没有被引用)。这意味着CONCAT()接受明文密码,并将存储在字段noncean中的内容附加到该密码,我也可以在SQL和PHP中生成SHA1密钥,对吗?我可以将此nonce字段用于其他用途吗?丢失密码令牌等?或者这是一个安全漏洞?@fabrik-(1)是的,您可以在其中任何一个中生成哈希,只要两者都支持相同的算法(例如MySQL没有HMAC)。(2) 这有两个方面:nonce的目的是为相同的密码获取不同的哈希值。因此,在知道nonce的情况下,攻击者可以在暴力强制时减少需要查看的字符串池。另一方面,攻击者只有在具有实际密码哈希时才能从nonce中获益,在这种情况下,他可能无论如何都具有nonce(来自SQL转储等)。HMAC通过引入site_key缓解了所有这些问题。我的最后一条评论不应该被解读为我建议发送nonce-攻击者知道的越少,你就越安全。