Regular Expressions for password complexity

Specops Password Policy contains a number of granular complexity, history, and dictionary requirements for passwords and utilizes basic C.  However, we cannot always anticipate every customer’s unique password requirements.  In order to give our customers the flexibility to set unique rules for passwords and passphrases, we provide support for regular expressions, also known as regex.

Regular expressions are programmatic strings used to check whether an input string meets specific criteria.  In Specops Password Policy, the string we are checking is a requested new password or passphrase, and the policy filter will allow the new password/passphrase only if it matches the regular expression.

We’ve blogged on how to enter regular expressions in Password Policy in the past, but here we’ll take a deeper dive in to regular expression syntax and the power it gives you to create unique password or passphrase requirements.

RegEx Syntax and Common Examples for Passwords

The Building Blocks

We will start by reviewing some of the special symbols and characters used in regular expressions, and then show how you can use those building blocks to create regular expressions of your own:

Character Sets

Often you will want a regex (or part of a regex) to require any characters from a set or range.  To do this, you enter characters you want to match, enclosed in square brackets [].  For example:

[abc]

If any of the letters in the square brackets are entered into the input string (‘a’ OR ‘b’ OR ‘c’) the expression will match.  Sometimes customers want to require specific special characters in their password, again using a character set.  For example:

[!@#$%^&*()]

This will match on any one of those special characters enclosed within the square brackets.   To do the opposite, add a ^ character to the beginning of the set, immediately after the opening bracket:

[^!@#$%^&*()]

This will match on any character except those specified in the set: !@#$%^&*()

Ranges and Wildcards

We can also specify a range or multiple ranges of characters.  To match on any lowercase character:

[a-z]

To match on uppercase OR lowercase:

[a-zA-Z]

Uppercase, lowercase, and digits:

[a-zA-Z0-9].

Regex evaluates ranges based on the ASCII or Unicode values of the characters.  The English alphabet and the digits 0-9 are stored as consecutive ASCII values, which is why these range examples work.  This will not be the case with special characters; you will want to specify each special character you want to include or exclude individually in your regex.

Regular expressions also support wildcards shown in the table below:

Wildcard Description
\s Space, tab, line feed, carriage return
\S Matches any non-space character (inverse of \s)
\w Matches any word character (lowercase, uppercase, digits, underscore)
\W Matches any non-word character (inverse of \w)
\d Matches any digit 0-9
\D Matches any non-digit (Inverse of \d)
. Matches any character

Matching on a Number of Characters

If you want to require a specific number of characters, use the following operators, placed immediately after the character, character set, or wildcard you want to match on:

Syntax Description Examples
{x} Match on exactly x repetitions of the preceding character/set. a{8} = aaaaaaaa

.{8} = any 8 characters

[a-z]{8} = any 8 consecutive lowercase characters

{x,y} Match on between x and y repetitions.  Omit the y value to indicate no upper limit. [a-z]{6,8} = between 6 and 8 consecutive lowercase characters

[a-z]{6,} = at least 6 consecutive lowercase characters

* Match 0 or more repetitions. Shorthand for {0,}
+ Match 1 or more repetitions. Shorthand for {1,}

Positional Anchors

In all regular expressions, a ^ at the beginning of the regular expression indicates we should match only at the beginning of the input string.  Similarly, a $ at the end of your regex is a placeholder for the end of the string.  For example, to require the first character is an uppercase or lowercase letter:

^[a-zA-Z]

Similarly, to require the string ends with a lowercase character:

[a-zA-Z]$

As a best practice, when you build your complete regex, always start it with the ^ and end it with the $.  This will ensure the entire string (i.e. the new password) is compared against the regex and thereby providing the most predictable results.

Building your Strong Password Regular Expression – Examples

Now that we have the basic pieces, we can build some simple regular expressions:

Let’s start with the example from a previous Specops blog post, excluding some specific characters from passwords.  In this case, Swedish characters that might not be available on non-Swedish keyboards:

^[^åäöÅÄÖ]+$

You can now see the building blocks we used to create this:

^ [^åäöÅÄÖ] + $
Begin Any character except these six One or more of those End

Similarly, to require passwords include only specific special characters (this one is common for compatibility with third-party solutions using AD passwords):

^[a-zA-Z0-9!@#%]+$

^ [a-zA-Z0-9!@#%]+ $
Begin 1 or more characters consisting of any combination of uppercase, lowercase, digits, and !@#%. End

To require passwords start with a letter:

^[a-zA-Z].*$

^ [a-zA-Z] .* $
Begin Any uppercase or lowercase – as the first character in the string (immediately following the ^ anchor). .* means 0 or more of any character.  This matches literally nothing and everything.  It is a shorthand to say nothing from this point on (in this case, after that first letter we required) matters. End

To require passwords ends with a letter (i.e. not a digit, special character, or something else) – same building blocks, just swap the order:

^.*[a-zA-Z]$

That’s all for now. For more about Regular Expressions, stay tuned for our upcoming blog Regular Expressions for Passphrases.

(Last updated on December 13, 2022)

Tags:

darren siegel

Written by

Darren Siegel

Darren Siegel is a cyber security expert at Specops Software. He works as a lead IT engineer, helping organizations solve complex challenges within IT security. Darren has more than 15 years’ experience within Active Directory, IT security, servers, storage, virtualization, cloud, and identity and access management.

Back to Blog