构建激活/密码重置链接的最佳方法

构建包含激活或密码重置令牌的链接的最佳方法是什么?该URL将通过电子邮件发送,用户可以点击它来激活他们的帐户或重置他们的密码 . 这有很多线程,但似乎没有一致的方法,从安全和开发的角度来看,每种方法似乎都有优点和缺点:

  • 链接包括令牌作为查询字符串中的参数和电子邮件地址
http://www.example.com/activations/:token?email=joe@gmail.com

使用此方法,令牌在数据库中进行哈希处理,并使用电子邮件查找用户 . 然后使用像brycpt这样的库将令牌与数据库中的散列版本进行比较 . 似乎包括敏感数据,例如查询字符串中的电子邮件地址,exposes some security risks .

  • 链接仅包括令牌作为参数或查询字符串 .
http://www.example.com/activations/:token

这似乎是理想的解决方案,但我不知道如何比较令牌,除非存储在数据库中的令牌未被取消 . 从安全的角度来看,有些人认为token in the database doesn't need to be hashed,而其他人则认为token should be hashed . 假设我们在数据库中保留一个哈希标记,迭代数据库中的每个标记并与链接中的标记进行比较似乎非常耗时,特别是在拥有大量用户的应用程序中 . 所以也许我错了,但似乎使用这种方法需要我将令牌存储在数据库中 .

有人对最佳方法有什么想法吗?

回答(1)

3 years ago

没有反对使用仅包含令牌的方法2的参数 .

正确的是,只应将令牌的哈希值存储在数据库中(SQL注入) . 您看到的问题来自于使用BCrypt:

  • Bcrypt包含 salt ,它阻止在数据库中搜索令牌 .

  • 因为BCrypt适用 key-stretching 验证非常慢,所以无法检查每个存储的哈希值 .

这两种技术,即腌制和键拉伸,对于存储弱密码是强制性的,它们使得暴力破解变得不可行 . 因为我们的令牌是一个非常强大的“密码”(最少20个字符0-9 a-z A-Z),所以不需要这些技术,您可以在数据库中存储令牌的未加盐的SHA-256 . 可以使用SQL直接搜索这样的哈希 .

为了表明它真的很安全,让我们做一个简单的计算 . 一个20个字符的标记将允许7E35组合 . 如果我们可以计算出3 Giga SHA-256 per second,我们仍然期望找到一个匹配的年份大约3个月到12 000年 .

只需确保令牌是从加密随机源创建的 .