Walkthrough: Validating That Passwords Are Complex (Visual Basic)

This method checks for some strong-password characteristics and updates a string parameter with information about which checks the password fails.

Passwords can be used in a secure system to authorize a user. However, the passwords must be difficult for unauthorized users to guess. Attackers can use a dictionary attack program, which iterates through all of the words in a dictionary (or multiple dictionaries in different languages) and tests whether any of the words work as a user's password. Weak passwords such as "Yankees" or "Mustang" can be guessed quickly. Stronger passwords, such as "?You'L1N3vaFiNdMeyeP@sSWerd!", are much less likely to be guessed. A password-protected system should ensure that users choose strong passwords.

A strong password is complex (containing a mixture of uppercase, lowercase, numeric, and special characters) and is not a word. This example demonstrates how to verify complexity.

Example

Code

''' <summary>Determines if a password is sufficiently complex.</summary>
''' <param name="pwd">Password to validate</param>
''' <param name="minLength">Minimum number of password characters.</param>
''' <param name="numUpper">Minimum number of uppercase characters.</param>
''' <param name="numLower">Minimum number of lowercase characters.</param>
''' <param name="numNumbers">Minimum number of numeric characters.</param>
''' <param name="numSpecial">Minimum number of special characters.</param>
''' <returns>True if the password is sufficiently complex.</returns>
Function ValidatePassword(ByVal pwd As String, 
    Optional ByVal minLength As Integer = 8, 
    Optional ByVal numUpper As Integer = 2, 
    Optional ByVal numLower As Integer = 2, 
    Optional ByVal numNumbers As Integer = 2, 
    Optional ByVal numSpecial As Integer = 2) As Boolean

    ' Replace [A-Z] with \p{Lu}, to allow for Unicode uppercase letters.
    Dim upper As New System.Text.RegularExpressions.Regex("[A-Z]")
    Dim lower As New System.Text.RegularExpressions.Regex("[a-z]")
    Dim number As New System.Text.RegularExpressions.Regex("[0-9]")
    ' Special is "none of the above".
    Dim special As New System.Text.RegularExpressions.Regex("[^a-zA-Z0-9]")

    ' Check the length.
    If Len(pwd) < minLength Then Return False
    ' Check for minimum number of occurrences.
    If upper.Matches(pwd).Count < numUpper Then Return False
    If lower.Matches(pwd).Count < numLower Then Return False
    If number.Matches(pwd).Count < numNumbers Then Return False
    If special.Matches(pwd).Count < numSpecial Then Return False

    ' Passed all checks.
    Return True
End Function

Sub TestValidatePassword()
    Dim password As String = "Password"
    ' Demonstrate that "Password" is not complex.
    MsgBox(password & " is complex: " & ValidatePassword(password))

    password = "Z9f%a>2kQ"
    ' Demonstrate that "Z9f%a>2kQ" is not complex.
    MsgBox(password & " is complex: " & ValidatePassword(password))
End Sub

Compile the code

Call this method by passing the string that contains that password.

This example requires:

Security

If you're moving the password across a network, you need to use a secure method for transferring data. For more information, see ASP.NET Web Application Security.

You can improve the accuracy of the ValidatePassword function by adding additional complexity checks:

  • Compare the password and its substrings against the user's name, user identifier, and an application-defined dictionary. In addition, treat visually similar characters as equivalent when performing the comparisons. For example, treat the letters "l" and "e" as equivalent to the numerals "1" and "3".

  • If there is only one uppercase character, make sure it is not the password's first character.

  • Make sure that the last two characters of the password are letter characters.

  • Do not allow passwords in which all the symbols are entered from the keyboard's top row.

See also