密码验证的这种实现方式看起来安全吗?

时间:2019-07-10 11:23:23

标签: security password-protection password-hash

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

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

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

    < / li>

因此,数据库总共包含#2盐腌哈希,#1盐和#2盐。

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

很抱歉,这个问题似乎很多余,但是我找不到有关该实现的任何答案。如果有人可以帮助我,那就太好了!

1 个答案:

答案 0 :(得分:0)

您看过Information Security Stack Exchange吗?例如。 this answer

客户端密码哈希通常被认为是无用且不必要的步骤,不会提高安全性。实际上,您的实现甚至可能会带来不必要的副作用,从而实际上降低了安全性:user enumeration

根据授权过程中第一步的实施方式,您可能会容易受到用户枚举的影响。我假设如果您的数据库中找不到匹配的用户,则您不会发送#1盐:

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

它也以另一种方式起作用:

  1. Anon尝试使用与用户名/电子邮件不匹配的用户名/电子邮件登录 数据库中的用户
  2. 当该用户确实存在时,API会发回该用户的#1盐
  3. Anon现在知道此用户名/电子邮件具有一个帐户

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

  1. Anon尝试使用与数据库中用户不匹配的用户名/电子邮件登录
  2. 由于该用户不存在,因此没有相应的#1盐可以发回
  3. 您的API发送回随机盐
  4. Anon使用相同用户名/电子邮件
  5. 再次尝试
  6. 您的API发送回与第一个不一致的另一个随机盐
  7. Anon可以推断出您的API既包含了两种盐,也试图绕过用户枚举

为解决此问题,您将不得不想出一种方法,始终响应同一用户名/电子邮件多次尝试发送相同的盐。但是对于每个未知用户,它都不应该是相同的盐,否则匿名将得出相同的推论。

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