如何在客户端检查密码强度?

信息安全 密码 密码管理
2021-08-18 00:44:16

我有一个网站,我的用户将使用他们选择的密码使用 JavaScript 客户端加密他们的RSA私钥。我应该如何确保他们使用强密码而不将其传输到服务器?

4个回答

您可以使用zxcvbn,这是一个检查密码强度的 JavaScript 库。

或者,HaveIBeenPwned API采用了一种有趣的方法来检查密码,而无需将密码发送到服务器:

  • 获取密码的 SHA1 哈希值。
  • 将其截断为五个字符。
  • 将此发送到服务器。
  • 服务器返回所有已知(不安全)密码的完整 SHA1 哈希值,并在其哈希值的开头使用这五个字符。
  • 客户端检查密码哈希是否在此列表中。

这样,您不需要提交整个密码,但客户端也不需要检索整个密码数据库。

我对密码强度问题的首选是NIST SP 800-63b:“数字身份指南:身份验证和生命周期管理”虽然这是美国政府的标准,但它也为我们其他人提供了良好的指导。

5.1.1.2 记忆的秘密验证者

...

在处理建立和更改记忆秘密的请求时,验证者应将预期秘密与包含已知常用、预期或泄露的值的列表进行比较。例如,列表可能包括但不限于:

  • 从以前的违规语料库中获得的密码。

  • 字典单词。

  • 重复或连续的字符(例如'aaaaaa'、'1234abcd')。

  • 特定于上下文的词,例如服务名称、用户名及其派生词。

如果在列表中找到选择的秘密,CSP 或验证者应告知订户他们需要选择不同的秘密,应提供拒绝的原因,并且应要求订户选择不同的值。

验证者应该向订户提供指导,例如密码强度计[Meters],以帮助用户选择一个强记忆的秘密。在拒绝上述列表中的记忆秘密之后,这一点尤其重要,因为它不鼓励对列出的(并且可能非常薄弱的​​)记忆秘密进行微不足道的修改[黑名单]。

请注意他们建议使用强度计(如 zxcvbn)只是作为 UI 辅助工具,但实际执行是针对黑名单进行的。

根据我的经验,实现这一点的最佳方法是使用客户端(javascript)基于熵的强度计,如zxcvbn来帮助用户清除明显较弱的密码短语。然后,当他们单击提交时,对 HaveIBeenPwned 等黑名单数据库进行 REST 调用。请注意,HaveIBeenPwned API 旨在避免泄露用户的实际密码,甚至泄露给 HaveIBeenPwned 管理员,正如@Sjoerd 在他们的回答中所描述的那样。

测量密码熵不是一件容易的事,而且基本上是不可行的。如果足够努力,任何系统或测量都可以被规避。如果用户真的想要,他们甚至可以使用类似💩.

最好为用户提供有关如何选择好的密码的指导,例如:

建议使用密码管理器生成一个长的、随机的密码并将其存储在安全的地方。

如果无法使用密码管理器,建议使用 Diceware 生成足够好的密码。

... 等等等等 ...

“密码强度”不是一个明确定义的指标。在实现这样的检查器时,请记住,大多数库仍然执行过时和错误的旧 NIST 指南(特殊字符、数字、废话)。

密码强度最强的指标是长度要求一个相当高的最小长度(2019 年)大约是 12 个字符或 16 个字符用于重要的事情,这是您可以拥有的最强大的单项检查。Mike 已经包含了相关的 NIST 建议以获取更多详细信息。

如果您使用库,请选择实施当前NIST 指南的库,而不是旧的。