【问题标题】:Does this implementation of password authentication seem secure?这种密码认证的实现看起来安全吗?
【发布时间】:2019-11-20 00:29:36
【问题描述】:

我正在创建一个需要安全执行身份验证的 Web 应用程序。阅读大量文章和帖子,我对实现得出以下结论。

  1. 前端密码散列:使用 bcrypt,我将使用唯一的盐对纯文本密码进行散列。该盐存储在每个用户的数据库中。然后将此 #1 salted-hash 发送到 API。

  2. 后端密码散列:使用 PBKDF2,#1 salted-hash 再次与另一个唯一的 salt 进行散列,生成 #2 salted-hash,然后将其与 #2 salt 一起存储在数据库中。

因此,数据库总共有 #2 salted-hash、#1 salt 和 #2 salt。

因此,当授权发生时,#1 salt 用于对纯文本密码进行散列,从而创建 #1 salted-hash。然后转到 API 进行授权,我们从数据库中获取 #2 salt 以创建 #2 salted-hash,然后将其与数据库中的 #2 salted-hash 进行比较以进行授权。

对不起,如果这个问题看起来多余,但我找不到任何特定于实现的答案。如果有人可以帮助我,那就太好了!

【问题讨论】:

    标签: security password-protection password-hash


    【解决方案1】:

    您是否查看过信息安全堆栈交换?例如。 this answer.

    客户端密码散列通常被认为是无用且不必要的步骤,不会提高安全性。事实上,您的实现甚至可能会产生有害的副作用,实际上会降低安全性:user enumeration

    根据您在授权期间实施第一步的方式,您可能容易受到用户枚举的攻击。如果在您的数据库中找不到匹配的用户,我假设您不会发回 #1 salt:

    1. Anon 尝试使用与您数据库中的用户不匹配的用户名/电子邮件登录
    2. 由于此用户不存在,因此没有相应的 #1 salt 可发回
    3. 您的 API 不会发回 salt,或者更糟糕的是,会发送“未找到用户”响应。无论哪种方式,anon 现在都知道此用户名/电子邮件没有帐户

    反之亦然:

    1. Anon 尝试使用与 数据库中的用户
    2. 由于该用户确实存在,API 会发回该用户的 #1 salt
    3. Anon 现在知道此用户名/电子邮件有一个帐户

    为避免这种用户枚举,如果没有找到匹配的用户,您的 API even 应该发回 #1 salt,甚至更多,它应该始终发送 same盐以响应相同的用户名/电子邮件,否则可能会发生这种情况:

    1. Anon 尝试使用与您数据库中的用户不匹配的用户名/电子邮件登录
    2. 由于此用户不存在,因此没有相应的 #1 salt 可发回
    3. 您的 API 发回随机盐
    4. Anon 再次尝试使用 相同 用户名/电子邮件
    5. 您的 API 发回 另一个与第一个不同的随机盐
    6. Anon 可以推断您的 API 由两种盐组成,以试图规避用户枚举

    要解决此问题,您必须想出一种方法,始终发送相同的 salt 以响应多次尝试的未知用户名/电子邮件。但它不应该对每个未知用户都使用相同的盐,否则会做出相同的扣除。

    总而言之,这似乎是不必要的复杂性。这可能是为什么客户端密码散列不被认为是一件好事的原因之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多