【问题标题】:Best way to build an activation/password reset link建立激活/密码重置链接的最佳方式
【发布时间】:2017-06-04 14:31:55
【问题描述】:

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

  1. 链接在查询字符串中包含令牌作为参数和电子邮件地址

    http://www.example.com/activations/:token?email=joe@gmail.com
    

    通过这种方法,令牌在数据库中进行哈希处理,电子邮件用于查找用户。然后使用 brycpt 之类的库将令牌与数据库中的散列版本进行比较。似乎包含敏感数据,例如查询字符串中的电子邮件地址,exposes some security risks。

  2. 链接仅包含令牌作为参数或查询字符串。

    http://www.example.com/activations/:token
    

    这似乎是理想的解决方案,但我不知道如何比较令牌,除非存储在数据库中的令牌未经过哈希处理。从安全的角度来看,一些人认为token in the database doesn't need to be hashed,而另一些人则认为token should be hashed。假设我们在数据库中保留一个散列令牌,遍历数据库中的每个令牌并与链接中的令牌进行比较似乎非常耗时,尤其是在具有大量用户的应用程序中。所以也许我对此有误,但似乎使用这种方法需要我将令牌存储在未散列的数据库中。

有人对最佳方法有任何想法吗?

【问题讨论】:

    标签: security passwords token reset activation


    【解决方案1】:

    没有反对使用仅包含令牌的方法 2。

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

    1. Bcrypt 包含一个 salt,可防止在数据库中搜索令牌。
    2. 由于 BCrypt 应用了key-stretching,因此验证速度非常慢,因此无法检查每个存储的哈希值。

    这两种技术,salting 和 key-stretching,对于存储弱密码是强制性的,它们使暴力破解变得不切实际。因为我们的令牌是一个非常强大的“密码”(至少 20 个字符,0-9 a-z A-Z),所以不需要这些技术,您可以将令牌的未加盐 SHA-256 存储在数据库中。这样的散列可以直接用 SQL 搜索。

    为了证明它真的很安全,让我们做一个简单的计算。 20 个字符的标记将允许 7E35 组合。如果我们可以计算出3 Giga SHA-256 per second,我们仍然预计大约需要 3'700'000'000'000'000'000 年才能找到匹配项。

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

    【讨论】:

    • 感谢您的回答!我一直在使用 bcrypt 来散列,所以我从来没有想过我可以在不使用盐的情况下进行散列!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 2010-11-07
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    相关资源
    最近更新 更多