为什么不使用当前的哈希密码来签署重置令牌?

Why not using current hash password to sign the reset token?

我已经通读了许多关于创建用户重置密码令牌的最佳实践指南。他们都说我们应该创建另一个数据库 table 并存储令牌的哈希值。

我想到为什么我们不重新使用当前的哈希密码来签署重置令牌?我们用该令牌通过电子邮件发送给用户,然后检查它们是否匹配。

如果用户修改密码,token将失效,确保一次性使用。所以现在我们不必添加额外的 table.

不确定我是否遗漏了什么?

好吧,这样做不会引入可直接利用的主要漏洞,但请考虑一些事情,看看为什么我认为它不会真正被推荐。

任何知道密码的人都知道密码散列。它可能不是实际用户,但如果作为攻击者,我不想直接尝试密码,因为这太吵了,进入日志,引发警报等等。相反,我让用户以某种方式更改他们的密码(例如,作为一个中间人,我拦截所有登录响应或其他任何方式,这无关紧要)然后我通过尝试更改密码来猜测他们的密码,知道唯一的秘密用于令牌。这至少可能会破坏可审计性。

加密算法有时也有弱点。不太可能,但如果已知足够多的密文或散列(有些可能带有明文),这样的弱点可能允许找出密钥的一部分。您不希望攻击者永远能够找到用户密码,尤其是因为不幸的是,这些密码往往会被重复使用。

所以基本上这一切都有点微妙,也许只是复杂攻击中的一个组成部分,但你不应该超出他们的目的使用秘密。如果这样做,弱点就会联系在一起,一个组件的弱点(在这种情况下是密码重置)将成为另一个组件(密码存储)的弱点。最好将不同的东西分开,从而将它们的漏洞分开(如果你愿意,可以减少漏洞利用的影响)。