Regex that validates Active Directory default password complexity

六月ゝ 毕业季﹏ 提交于 2019-12-18 06:17:31

问题


I have a list of passwords that I need to examine and determine if they meet the default 3 of 4 rule for AD.

Rule is contain 3 of the 4 following requirements: lower case character (a-z) upper case character (A-Z) numeric (0-9) special character ( !@#$%^&*()_+= )

I am still learning Regex. I know how to select only those that meet any one character case, but I am not sure how to do 3 of 4.

As a side note, the AD Complexity has two more subtleties that are important (but out of scope of the original question).

It is really 3 of 5. The fifth is Unicode character. Be nice to update the Regex with that.

The other is you cannot have the sAMAccountName value in whole in the password (case insensitive), nor if you split the displayName value into tokens split upon space, comma, dash, underscore, pound, pipe and something else those tokens (3 chars and longer) cannot be in whole in the password, case insensitive.


回答1:


If you really want one big regex it would be something like this:

(?=^.{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]))^.*

Note that it also enforces password length to be between 8 and 255 characters. You can change the "{8,255}" portion in the first section to adjust the length requirements. It is also worth noting that this is working for me in a standard ASP.NET RegularExpressionValidator control.

Matches: "Passw0rd" "passW@rd" "1B2a345@#$%"

Non-Matches: "123123123" "Password" "asdf&"

Source (Matthew Hazzard via RegExLib.com)




回答2:


Does it have to be all one big regex? You could do 4 regexes, each checking one thing and then make sure 3 of the 4 are matches. That would be easier, less error prone and more maintainable.




回答3:


You will have to build up the regular expression like this:

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

I'm not sure if I escaped the special characters correctly. It's kind of dependant on the language/toolkit you're using.




回答4:


I edited the @saul-dolgin answer to exactly match with the valid charset specified in the question (not a a non-alfanumeric character [^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 forces passwords to have only characters from their list. I also changed the Maximum lenght to 20.



来源:https://stackoverflow.com/questions/774569/regex-that-validates-active-directory-default-password-complexity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!