Check password rules
How can we check password rules? Do they meet the complexity requirements? This article explains various methods for checking compliance with password policies in an Active Directory domain.
A practical example is the implementation of a self-service password change portal to ensure compliance and provide users with an easy way to manage their passwords.
Index
Why do Password rules exist?
Simplicity and security are two keywords that very few people would probably mention in the same sentence. The need for secure methods to verify authorized access to IT resources is certainly undeniable. Essentially every resource today is connected to IT or secured by IT. It is no longer just access to files in the virtual world that is protected, but also relates to the real world:
- printers,
- rooms,
- vehicles,
- production machines, etc.
It is in the nature of things that security methods are usually cumbersome, as this is the only way they can successfully ward off unauthorized access. However, they should only be as complicated as necessary, otherwise the user will find ways to make it easier for themselves, and thus for the attacker, which would counteract the security efforts.
Technological progress also helps with simplification. Many methods exist today to make user authentication uncomplicated. The best known are biometric methods such as fingerprint and facial recognition.
As advanced as these methods are, in most organizations they collide with reality. Additional hardware and compatibility with corresponding protocols are required for this. However, a large number of software programs are not yet able to cover this. Consequently, the password remains the most widely used authentication method.
To ensure that the password is still as secure as possible, various complexity rules must be observed to make it as difficult as possible for an attacker to guess the password. The framework conditions for this are:
- a minimum password length,
- uniqueness and
- the use of many different character types.
Passwords should also be changed regularly. As this usually bothers users and they therefore tend to count up a number at the end of the password, the password history is also checked.
Help for users
As we want to make it as easy as possible for users, we also want to help them with the tedious but necessary task of changing their passwords regularly.
Unfortunately, Microsoft is not very helpful here. If we have not designed our new password according to the complexity rules, Windows only gives us a very succinct answer:
This message is not meaningful for the user as it does not contain any information about which entries are still missing in the password. We would like to create a self-service password change portal to provide assistance. Before the password is sent to the Active Directory domain, the portal should tell the user what is still missing so that the password complies with the rules.
What password rules does the Active Directory recognize?
Before we deal with the portal, we must first determine which rules or policies exist and how they can be configured.
The default password policy is applied to all user accounts in the domain and is defined in the default domain policy. We can configure the Group Policies settings in the Group Management Editor. To do this, we open the Administrative Tools.
There we go to the Default Domain Policy and open the edit view.
In the edit view of the default domain policy, the password settings can be found under “Computer Configuration\Policies\Windows Settings\Security Settings\Account Policies\Password Policy”.
You can also use the PowerShell command Get-ADDefaultDomainPasswordPolicy to quickly retrieve the current settings.
For the sake of completeness, it should be mentioned that specific password policies can also be defined for a certain group of users, e.g. admins. The Fine Grained Password Policy is used for this. However, this is a topic for a separate article.
Password policy settings in the Active Directory
Now that we have found out where the policies can be configured, let’s take a detailed look at the settings we can make.
Rule |
Meaning |
Enforce password history |
How many password changes should a password be saved so that it cannot be reused. If the value is 24, a password can only be reused after 24 changes. |
Maximum password age |
What is the maximum number of days a password can remain unchanged? |
Minimum password age |
How many days does a password have to exist before it can be changed again? |
Minimum password length |
What is the minimum length of a new password? |
Password must meet complexity requirements |
The password must meet the complexity requirements. |
Store password using reversible encryption |
This setting should not be activated in most cases, as it is effectively the same as saving the password in plain text. We will therefore not go into this further in this article. |
Importance of complexity requirements
I would like to take a closer look at the complexity rules for a password, as they are essential for the quality of a password. The complexity rules are intended to ensure that a password is as random and strongly deviating from a normal text as possible. This should make it more difficult for an attacker to guess the password or find it out using dictionary attacks.
The following rules are checked via the Group Policy in the Active Directory:
- The user account name (samAccountName) must not be included
- No parts of the user’s full name (cn, name) may be included. This is the case if more than 2 following letters of the name are included.
E.g. Frank Anger may not have a password ‘P@fraKle123! - The password must be at least 6 characters long.
- The password must contain at least 3 of the following types of characters:
- Capital letters A-Z
- Lower case letters a-z
- Digits 0-9
- Special characters: ‘-!”#$%&()*,./:;?@[]^_`{|}~+<=>
The rules are checked each time the password is changed.
Methods for checking the password rules
Once we have established what good password rules are, we can move on to the methods for checking compliance with these rules.
As mentioned at the beginning, Windows is not much help here as it does not offer any corresponding APIs. The only useful method is the NetValidatePasswordPolicy function (https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netvalidatepasswordpolicy).
This method is mainly used for applications to check whether their own managed passwords comply with the Active Directory Password Policy. For example, SQL Server can use this function for SQL Server authentication. An implementation example is given in the following link.
pinvoke.net: NetValidatePasswordPolicy (advapi32)
As you can see in the link above, this method is fairly complex to implement with programming knowledge. In the end, however, it only provides us with the information as to whether the password complies with the complexity rules or not. There is no meaningful feedback.
Therefore, we only have the option of implementing the password check ourselves and checking compliance with each rule separately. In this article, I use PowerShell to demonstrate some implementation examples.
Check password rules with PowerShell
In PowerShell, we can check the input for various rules and at the same time introduce our own quality criteria.
A good option is to use regular expressions with the Matches method. This allows us to check for any text content. In the following, we will see what a check method could look like for each complexity criterion.
Checking the password length
1 2 3 4 5 6 7 8 9 10 |
$length = $password.length if( $length -lt 6 ) { Write-Host “Password need at least 6 characters.” } if( $length -gt 20 ) { Write-Host “The password must not contain more than 20 characters.“ } |
Checking the minimum number of capital letters
1 2 3 4 5 6 7 |
$uppercaseCount = [regex]::Matches($password, “[A-Z]").Count if( $uppercaseCount –lt 3 ) { Write-Host “Password need at least 3 uppercase characters.” } |
Checking the minimum number of lowercase letters
1 2 3 4 5 6 7 |
$lowercaseCount = [regex]::Matches($password, “[a-z]").Count if( $lowercaseCount –lt 3 ) { Write-Host “Password need at least 3 lowercase characters.” } |
Checking the minimum number of digits
1 2 3 4 5 6 7 |
$digitCount = [regex]::Matches($password, “\d").Count if( $digitCount –lt 3 ) { Write-Host “Password need at least 3 digits.” } |
Checking the minimum number of special characters
1 2 3 4 5 6 7 8 |
$specialCharCount = [regex]::Matches($password, “[-!`"#$%&()*,./:;?@[\]^_`{|}~+<=>]").Count if( $ specialCharCount –lt 3 ) { Write-Host “Password need at least 3 special characters.” } |
Check for forbidden words
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$bannedWords = @($samAccountName, $displayName, $sn, $givenName) $bannedWordsSplit = @() $tab = [char]9 foreach ($word in $bannedWords) { $wordSplit = $word.Split(@(' ', ',', '.', '_', ';', $tab)) $bannedWordsSplit += $wordSplit; } foreach ($word in $bannedWordsSplit) { $passwordTest = $password.ToLowerInvariant() $wordTest = $word.Trim().ToLowerInvariant() if($passwordTest.Contains($wordTest)) { Write-Host “The password must not contain the word '$word'.“ } } |
Check for parts from the user name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
function Contains-Parts { param ( [string]$password, [string]$bannedWord ) $maxLength = 2 $testPassword = $password.ToLowerInvariant() $testBannedWord = $bannedWord.ToLowerInvariant() for ($i = 0; $i -le ($testBannedWord.length - $maxLength); $i++) { $bannedWortPart = $testBannedWord.Substring($i, $maxLength) if ($testPassword.Contains($bannedWortPart)) { return $true } } return $false } $bannedWords = @($cn, $displayName, $samAccountName) foreach ($word in $bannedWords) { if(Contains-Parts -password $password -bannedWord $word) { Write-Host “The password must not contain parts of the word '$word'.“ } } |
Checking the password history
Unfortunately, we cannot easily check the password history using a separate function. The password history of a user cannot be checked via an API.
However, we can use the PowerShell command Set-ADAccountPassword to ensure the history after successfully checking the password quality.
It is important that the -Reset switch is not used for this, as this bypasses the password history check.
Set-ADAccountPassword -Identity $user -OldPassword $oldPassword -NewPassword $newPassword
Password-Change Portal
With the help of the PowerShell functions, we now have all the tools we need to set up a password change portal for users.
For our customer, we were able to integrate this very easily into the self-service side of the IDM-Portal. We execute the PowerShell functions via our IDM-Portal PowerShellProvider service, which makes it easy to integrate PowerShell commands into the IDM-Portal.
Conclusion
In this article, we have learned how important a high-quality password is and what its characteristics are. We have also developed methods to give our users meaningful feedback on their new passwords. With this help, we can enable users to implement the requirements for a secure password easily and effectively.
More about FirstWare IDM-Portal
FirstWare IDM-Portal from FirstAttribute is an integrated Identity and Access Management (IAM) solution that enables the automated management of users and their authorizations, whether on-premises or in the cloud.
This portal integrates all facets of identity and access management and enables centralized access to identity and directory services.