阅读 this excellent answer关于密码散列和想知道如何实现它:
Generate a nonce for each user; this alone defeats the rainbow table. This is a random number that, depending on the range, expands how many resulting hashes there are.
所以除了用户密码之外,我的数据库中还存储了一个唯一 token ?
原帖中的示例代码:
function hash_password($password, $nonce) {
global $site_key;
return hash_hmac('sha512', $password . $nonce, $site_key);
}
我如何使用此代码验证密码?让我解释一下:
当用户提交他的密码时,我需要生成它的哈希值以检查电子邮件地址和哈希密码匹配的现有数据库行。当我对用户的 $nonce
一无所知时,如何选择这一行?我错过了什么吗?也许我需要仅通过他的电子邮件地址来选择用户,然后再验证密码哈希?
顺便说一句,你推荐这种哈希方法吗?
最佳答案
我认为您已经确定了这个想法。同样的概念也适用于一般的 UNIX 风格加盐密码 - 以明文形式存储盐和密码并通过用户名检索它,然后使用加盐和提供的密码生成新的哈希值以与存储的值进行比较。
由您决定是否信任您的数据库服务器(及其连接)使用数据库支持的哈希算法并让数据库进行计算:
SELECT * FROM users WHERE email = 'email' AND password = SHA1(CONCAT('cleartextpass',nonce));
或者您可以在检索到所有匹配的电子邮件后在代码中进行数学计算。
编辑:ThiefMaster 关于区分丢失用户 和无效密码 的评论是典型的安全漏洞,它允许攻击者获取列表有效 用户名并专注于破解他们的密码,而不是在黑暗中钓鱼。我强烈建议反对它。
关于php - 如何正确实现 hash_hmac?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5579559/