参考 - 密码验证

时间:2018-01-19 16:53:57

标签: regex validation authentication passwords

通常,问题(特别是标记为的问题)会询问验证密码的方法。用户通常会寻求密码验证方法,包括确保密码包含特定字符,匹配特定模式和/或遵守最小字符数。这篇文章旨在帮助用户找到适当的密码验证方法,而不会大大降低安全性。

所以问题是:如何正确验证密码?

1 个答案:

答案 0 :(得分:51)

为什么密码验证规则不好?

我们自己的Jeff Atwood(Coding Horror的博主和Stack Overflow和Stack Exchange的联合创始人)在2017年3月写了一篇关于密码规​​则的博客,名为Password Rules are Bullshit。如果您还没有阅读这篇文章,我会敦促您这样做,因为它极大地反映了这篇文章的意图。

如果您从未听说过NIST (National Institute of Standards and Technology),那么您可能无法为您的项目使用正确的网络安全方法。在这种情况下,请查看他们的Digital Identity Guidelines。您还应该保持最新有关网络安全的最佳做法。 NIST Special Publication 800-63B (Revision 3)提到了以下有关密码规则的内容:

  

验证者不应强加其他组成规则(例如要求   不同特征类型的混合物或连续禁止   记忆秘密的重复字符。

即使是Mozilla关于Form data validation的文档,也会对密码规则(page archive here)感兴趣:

  

"您的密码长度必须介于8到30个字符之间,并且包含一个大写字母,一个符号和一个数字" (严重?)

如果您为密码强加组合规则会怎样?您限制潜在密码的数量,并删除与您的规则不符的密码排列。这允许黑客确保他们的攻击也一样! &#34;雅但是有一个千万亿(1,000,000,000,000,000或1x10 15 )密码排列&#34; 25-GPU cluster cracks every standard Windows password in <6 hours(95 8 = 6,634,204,312,890,625~6.6x10 15 密码)。

xkcd

如何验证密码?

1。不要创建自己的身份验证

  

完全停止要求密码,让人们使用Google,Facebook,Twitter,Yahoo或您感到满意的Internet driver's license有效形式登录。最好的密码   是one you don't have to store

来源:Jeff Atwood的Your Password is Too Damn Short

2。创建自己的身份验证

如果您必须创建自己的身份验证方法,请至少遵循经过验证的网络安全方法。以下两节(2.1和2.2)取自current NIST publication5.1.1.2 Memorized Secret Verifiers部分。

2.1。遵循PROVEN网络安全方法

NIST声明你应该

  • 要求用户选择的记忆秘密长度至少为8个字符。
    • Jeff Atwood建议普通用户的密码至少为10个字符,对于拥有更高权限的用户,密码应至少为15个字符(即管理员和版主)。
  • 允许用户选择的记忆密码长度不超过64个字符。
    • 理想情况下,你甚至不应该对此加上限制。
  • 允许所有打印ASCII(包括空格字符)和Unicode。
    • 出于长度要求的目的,每个Unicode代码点都应计为单个字符。
  • 将预期机密与包含已知常用,预期或受损的值的列表进行比较。例如:
    • 从以前的违规语料库中获取的密码。
    • 字典词。
    • 重复或连续字符(例如aaaaaa1234abcd
    • 特定于上下文的单词,例如服务名称,用户名及其派生词。
  • 向订户提供指导,例如密码强度计。
  • 实施速率限制机制,有效限制可在订阅者帐户上进行的失败身份验证尝试次数(请参阅Rate Limiting (Throttling))。
  • 如果有证据证明身份验证者妥协,则强制进行更改。
  • 允许索赔人在输入记忆密码时使用粘贴功能(便于使用密码管理器,这通常会增加用户选择更强记忆秘密的可能性)。

2.2。请勿使用本节中的任何方法!

同一出版物还声明您不应该

  • 截断秘密。
  • 允许订阅者存储未经身份验证的索赔人可以访问的提示
  • 在选择记忆的秘密时,提示订阅者使用特定类型的信息(例如&#34;您的第一只宠物的名字是什么?&#34;)。
  • 强加其他构图规则(例如要求不同字符类型的混合或禁止连续重复的字符)以备存记的秘密。
  • 要求记忆秘密可以任意更改(例如定期更改)。

有很多网站在解释如何创建&#34;正确的&#34; 密码验证表单:其中大部分已过时且不应使用。

3。使用密码熵

在继续阅读本节之前,请注意本节的目的不是为您提供推出自己的安全方案所需的工具,而是为您提供信息关于 当前安全方法验证密码的方式。如果你正在考虑创建自己的安全方案,你应该考虑三次并从StackExchange的安全社区阅读this article

3.1。密码熵概述

在最基本的级别,密码熵可以使用以下公式计算:

E = log2(R^L)

在上面的公式中:

  • E代表密码熵
  • R中唯一字符的字符数
  • L是密码中的字符数

这意味着R^L代表可能的密码数量;或者,就熵而言,耗尽所有可能性所需的尝试次数。

不幸的是,这个公式没有考虑的是:

  • 通用密码:即Password1admin
  • 姓名:即JohnMary
  • 常用词语:即英语theI
  • 反转/反转的字词:即drowssap(密码向后)
  • 字母替换(又名leet):即P@$$w0rd

为这些额外的考虑因素添加逻辑是一项巨大的挑战。有关可以添加到项目中的现有包,请参阅3.2。

3.2。现有密码熵项目

在撰写本文时,用于估计密码强度的最着名的现有库是zxcvbn by Dropbox(GitHub上的一个开源项目)。它已经过调整以支持 { {3}}

以错误的方式行事

但是,我理解每个人都有不同的要求,有时人们想要以错误的方式做事。对于那些符合这一标准的人(或者没有选择并且已经向您的经理提供了更多内容以及他们拒绝更新他们的方法),至少允许使用Unicode字符。您将密码字符限制为特定字符集(即确保存在小写ASCII字符a-z或指定用户可以输入或不能输入!@#$%^&*()的字符)的那一刻,您只需询问麻烦!

<强> P.S。永远不要相信客户端验证,因为它很容易被禁用。这意味着对于那些尝试使用 停止验证密码的人。有关详细信息,请参阅

以下正则表达式模式在所有编程语言中都不起作用,但在许多主要编程语言中都有效(JavaScript: client-side vs. server-side validation {{3 }})。请注意,以下正则表达式可能无法使用您的语言(甚至语言版本),您可能需要使用替代方案(例如:请参阅)。一些编程语言甚至有更好的方法来检查这种事情(即使用 Python regex matching Unicode properties)而不是重新发明轮子。使用Password Validation Plugin如果中讨论的或其他一些转换工具用于Unicode类,则以下内容有效。

如果您需要以防止输入控制字符,则可以使用模式[^\P{C}\s]在正则表达式匹配时提示用户。这将仅匹配不是空格字符的控制字符 - 即水平制表符,换行符,垂直制表符。

以下正则表达式确保8个字符长度的密码中至少存在一个小写,大写,数字和符号:

^(?=\P{Ll}*\p{Ll})(?=\P{Lu}*\p{Lu})(?=\P{N}*\p{N})(?=[\p{L}\p{N}]*[^\p{L}\p{N}])[\s\S]{8,}$
  • ^在行首处断言位置。
  • (?=\P{Ll}*\p{Ll})确保至少存在一个小写字母(在任何脚本中)。
  • (?=\P{Lu}*\p{Lu})确保至少存在一个大写字母(在任何脚本中)。
  • (?=\P{N}*\p{N})确保至少存在一个数字字符(在任何脚本中)。
  • (?=[\p{L}\p{N}]*[^\p{L}\p{N}])确保至少有一个不存在字母或数字的字符(在任何脚本中)。
  • [\s\S]{8,}匹配任何字符8次或以上。
  • $断言行尾的位置。

请自行决定使用上述正则表达式。你被警告了!