Validating Strong Pass Phrases Snippet

In case you missed it, the title isn't "Validating Strong Passwords" because by now the inherent weaknesses of traditional passwords are well-known. Even with pass phrases, enforcing "strong" by policy is a good idea to boost entropy.

Most of the available regular expressions check for at least one uppercase, lowercase and numeric character. What they all seem to miss is a declaration of acceptable characters in the first place. I've created a pair of suitable expressions to check against. One ensures that certain characters exist, the other ensures that only those characters exist. If my RegEx skills were better perhaps I could combine the two into a single expression.

The goal is to ensure a user's password is strong according to Microsoft's definition of a strong password, particularly:

  • at least seven characters long
  • contains at least one character from each of the four groups: uppercase, lowercase, numerals, and symbols found on the keyboard.

Since this will validate pass phrases rather than passwords the minimum length will be 14, not 7 (a number suggested by MS PSS lead Robert Hensing). On the upper bound, Windows (from NT forward) allows passwords of up to 128 characters so this method will accept that too. Note that the old limit was 14 characters and this boundary may be in effect on networks still configured to accept connections from older clients.

Other "strong" criteria exist (e.g. does not contain the user or company name, and does not contain a dictionary word) but we will stick to what we can cover with regular expressions. In the end, the OS or Active Directory will be the final arbiter, we just want to eliminate the bulk of invalid requests to update the password.

I've removed a few special characters from the list to demonstrate that you can and should customize this to suit your own needs, policy, or comfort level (in this case the \, <, >, and " characters).

Wherever you use this you will need to drop in the following reference:
using System.Text.RegularExpressions;

/// <summary>
/// Check whether the provided string is a strong password.
/// The string must contain at least one uppercaseone lowercase,
/// one numeral, and one special character.
/// The method allows uppercaselowercasedigits,
/// and keyboard characters except for\ < > "
/// </summary>
/// <param name="password">The password tovalidate.</param>
/// <returns>True if the password is a strong password, false otherwise.</returns>
public static bool IsStrongPassword(String password)
{
   // Special Characters (update here then cut & paste to 2 locations below)
   // \-\+\?\*\$\[\]\^\.\(\)\|`~!@#%&_ ={}:;  ',/

   // Defines minimum appearance of characters
   String ex1 = @"
      ^        # anchor at the start
      (?=.*\d)    # must contain at least one digit
      (?=.*[a-z])    # must contain at least one lowercase
      (?=.*[A-Z])    # must contain at least one uppercase
      (?=.*[\-\+\?\*\$\[\]\^\.\(\)\|`~!@#%&_ ={}:;  ',/])  # must contain at least one special character
      .{14,128}    # minmax length
      $        # anchor at the end"; 

   // Allow only defined characters
   String ex2 = @"
      ^        # anchor at the start
      [\w\-\+\?\*\$\[\]\^\.\(\)\|`~!@#%&_ ={}:;  ',/] # alphanumerics and special characters only
      {14,128}      # minmax length
      $        # anchor at the end"; 

   return (IsMatch(passwordex1RegexOptions.IgnorePatternWhitespace&&
      IsMatch(passwordex2RegexOptions.IgnorePatternWhitespace));
}

Generated using PrettyCode.Encoder

/// <summary>
/// Match a regular expression against a provided string.
/// </summary>
/// <param name="input">The input string to validate.</param>
/// <param name="pattern">The regular expression pattern used to
/// validate the input.</param>
/// <param name="options">A bitwise OR combination of the
/// RegExOption enumeration values</param>
/// <returns>True if the parameters produce a match, false
/// otherwise.</returns>
public static bool IsMatch(String inputString patternRegexOptions options)
{
   System.Text.RegularExpressions.Regex regex = new Regex(pattern,options);
   System.Text.RegularExpressions.Match m = regex.Match(input);
   if (m.Success)
      return true;
   else
      return false;
}


Generated using PrettyCode.Encoder

No Comments