【问题标题】:Regex that validates Active Directory default password complexity验证 Active Directory 默认密码复杂性的正则表达式
【发布时间】:2010-10-20 22:45:10
【问题描述】:

我有一个密码列表,我需要检查并确定它们是否符合 AD 的默认 3 of 4 规则。

规则包含以下 4 个要求中的 3 个: 小写字符 (a-z) 大写字符 (A-Z) 数字 (0-9) 特殊字符( !@#$%^&*()_+= )

我还在学习正则表达式。我知道如何只选择满足任何一种字符大小写的那些,但我不确定如何做 3 of 4。

附带说明,AD 复杂性还有两个重要的微妙之处(但超出了原始问题的范围)。

实际上是 3 of 5。第五个是 Unicode 字符。很高兴用它来更新正则表达式。

另一个是您不能在密码中包含整个 sAMAccountName 值(不区分大小写),也不能将 displayName 值拆分为按空格、逗号、破折号、下划线、磅、管道和其他标记拆分的标记( 3个字符及以上)密码不能是完整的,不区分大小写。

【问题讨论】:

    标签: regex active-directory passwords


    【解决方案1】:

    如果你真的想要一个大的正则表达式,它会是这样的:

    (?=^.{8,255}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*
    

    请注意,它还强制密码长度在 8 到 255 个字符之间。您可以更改第一部分中的“{8,255}”部分以调整长度要求。还值得注意的是,这在标准 ASP.NET RegularExpressionValidator 控件中对我有用。

    匹配项:“Passw0rd”“passW@rd”“1B2a345@#$%”

    不匹配:“123123123”“密码”“asdf&”

    Source(Matthew Hazzard 来自 RegExLib.com)

    【讨论】:

    • 只是测试这种方法让我发现 't3st33#3' 显示为有效的情况,但 't3st33#33' 没有。
    • @geoffc 我使用online validator 进行了快速测试,发现't3st33#3'(有效)、't3st33#33'(有效)和'password1'(无效)的正确结果)。也许检查您的正则表达式选项并确保它正在评估匹配启用区分大小写
    • 其实这是一个好点!也许是区分大小写!当我使用 4 个单独的正则表达式方法时,我发现了这一点。
    • 您应该使用符号字符集[!@#\$%\^&\*\(\)_\+=],而不是使用[^A-Za-z0-9](没有字母数字)。小心转义字符。
    • 人们应该知道,虽然这可能得到了很多支持,但它并不是很好。 AD 使用的 5 个字符复杂度类是根据 unicode 定义的,而这个答案给出了一个只支持 ASCII 文本密码的正则表达式。因此,美国以外的用户可能会发现这个正则表达式拒绝了他们的密码,尽管真正的 AD 接受了它。来源:technet.microsoft.com/en-us/library/cc786468(v=ws.10).aspx
    【解决方案2】:

    它必须是一个大的正则表达式吗?你可以做 4 个正则表达式,每个检查一件事,然后确保 4 个中有 3 个匹配。这样会更容易、更不容易出错并且更易于维护。

    【讨论】:

    • 一个大的正则表达式会更容易使用。我还没有决定我将使用它的工具。倾向于 Perl,但实际上可能会在 DirXML 脚本中的 Novell Identity Manager 中使用它,因为它已经在 IDM 系统中。
    【解决方案3】:

    您必须像这样构建正则表达式:

    rule = [ "[a-z]", "[A-Z]", "[0-9]", "[!@#$%\^\&\(\)\+=]" ]
    
    regex = ""
    first = true
    for a in 0..3:
      for b in 0..3:
        if a == b: continue
        for c in 0..3:
          if a == c or b == c: continue
          if not first:
            regex += "|"
          regex += "(" + rule[a] + ".*" + rule[b] + ".*" + rule[c] + ")"
          first = false
    

    我不确定我是否正确转义了特殊字符。这在某种程度上取决于您使用的语言/工具包。

    【讨论】:

      【解决方案4】:

      我编辑了@saul-dolgin 答案以与问题中指定的有效字符集完全匹配(不是非字母数字字符[^A-Za-z0-9]):

      (?=^[A-Za-z\d!@#\$%\^&\*\(\)_\+=]{8,20}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[!@#\$%\^&\*\(\)_\+=])(?=.*[a-z])|(?=.*[!@#\$%\^&\*\(\)_\+=])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[!@#\$%\^&\*\(\)_\+=]))^.*
      

      Microsoft 强制密码仅包含其列表中的字符。 我还将最大长度更改为 20。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 2011-02-04
      • 2013-01-19
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多