安全“重置密码”的强算法

Posted

技术标签:

【中文标题】安全“重置密码”的强算法【英文标题】:Strong Algorithm for "resetting password" securely 【发布时间】:2012-02-29 20:28:20 【问题描述】:

我正在开发一种强大的算法来安全地重置密码并从用户社区寻找反馈。这是我到目前为止的想法(在What are best practices for activation/registration/password-reset links in emails with nonce 的帮助下)

密码重置过程如下: 当用户请求“通过电子邮件将重置密码链接发送给他们”时......

    生成 $salt 提示用户输入他们希望将“重置密码”链接发送到的 $email 地址。 检索 $key(=秘密的用户预定义敏感帐户数据,只有他们知道,例如他们出生的城市或 SSN#Last4) 创建 $nonce = hash($email . $key) 保存到表格: $nonce (PK) $盐 $exp_date 创建 $hash =hash($salt . $email . $key) 通过电子邮件向用户发送重置密码的链接@URL=...?hash=$hash

当用户点击我们发送给他们的链接时,它会将他们带到一个表单中:

输入$email 输入 $newPassword 确认 $newPassword 提示输入关键字段...即:“输入您出生的城市:”输入 $key

当用户提交此表单时...

    从 URL 中检索 $hash 重新创建 $nonce = hash($email . $key) 使用 $nonce 从我们的表中检索 $salt(如果未过期)。 如果 hash($salt . $email . $key) == $hash from URL,那么验证是好的!所以我们... 更新数据库中的用户密码 否则,我们拒绝更改密码的尝试

注意事项:

在处理之前,所有 $email 和 $key 响应都会被修剪并小写以避免混淆。 定期维护任务 sproc 应定期删除所有过期的 nonce 以保持表清洁

你怎么看?

【问题讨论】:

与在服务器端保存足够长的随机令牌并通过邮件将其发送给用户相比,有什么更安全的呢?我不明白。 Niklas:任何拥有令牌的人都可以破解它。 (即任何可以窥视用户电子邮件帐户的人 - 邪恶的系统管理员,在原始用户忘记注销后使用公共 PC 的下一个人等)。 要获得链接,必须破解电子邮件帐户。您可以通过在密码重置表单中添加安全问题或询问“秘密的用户定义的敏感帐户数据”来提高安全性,但这不需要散列内容(或者我错过了什么?) 你的‘nonce’不是nonce,因为它既不是任意的也不是只使用一次。如果您请求两次密码重置,您将获得相同的随机数。 @DeborahCole:如果有人可以访问您的数据库,那么您就输了。就这么简单,真的。 【参考方案1】:

几个问题。通过将 nonce 存储到数据库中,您完全破坏了 nonce 的含义,从而削弱了应用程序的整体安全性。通过存储盐,您也削弱了安全性,因为如果我获得对数据库的访问权限,我知道您用于帐户的“随机”盐值,因此使您面临彩虹表攻击。

当用户提交此表单时...

Retrieve $hash from the URL
Recreate $nonce = hash($email . $key)
Use $nonce to retrieve $salt from our table (if unexpired).
If hash($salt . $email . $key) == $hash from URL, then the Validation is GOOD!, so we... Update the user's password in the database
Otherwise, we refuse the attempt to change the password

上面的内容被破坏了。因为我知道你存储了 nonce,所以你降低了应用程序的安全性,进一步通过存储盐,你也削弱了安全性。鉴于上述情况,如果我有电子邮件 + 散列算法(你必须假设我知道你的算法),我可以检索盐并推断随机数。因此我可以“快速”破坏整个数据库。

【讨论】:

以上是关于安全“重置密码”的强算法的主要内容,如果未能解决你的问题,请参考以下文章

重置 ASP.NET 密码 - 安全问题?

以 html 帖子形式存储重置密码令牌是不是安全?

允许用户重置密码的最安全方法是啥

mysql安全模式重置密码

电脑忘记密码?

Ubuntu系统安装MySQL后如何重置密码