Singulink.Cryptography.PasswordMatcher 1.0.0

Prefix Reserved
dotnet add package Singulink.Cryptography.PasswordMatcher --version 1.0.0
                    
NuGet\Install-Package Singulink.Cryptography.PasswordMatcher -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Singulink.Cryptography.PasswordMatcher" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Singulink.Cryptography.PasswordMatcher" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Singulink.Cryptography.PasswordMatcher" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Singulink.Cryptography.PasswordMatcher --version 1.0.0
                    
#r "nuget: Singulink.Cryptography.PasswordMatcher, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Singulink.Cryptography.PasswordMatcher@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Singulink.Cryptography.PasswordMatcher&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Singulink.Cryptography.PasswordMatcher&version=1.0.0
                    
Install as a Cake Tool

Singulink.Cryptography.PasswordMatcher

Chat on Discord View nuget packages Build and Test

Password Matcher can be thought of as a dictionary attack password generator, but in reverse. Instead of generating candidate passwords, it recognizes them: a composable matcher grammar checks whether a password is built entirely from the words, phrases and decorations that dictionary attacks combine, including contextual values such as your application or service name and the user's name, email address and company. Passwords that are vulnerable to simple dynamic dictionary attacks are detected without maintaining a specialized password dictionary, which makes it easy to follow the latest NIST password guidelines and give users wide latitude in choosing their passwords while still protecting them.

We are a small team of engineers and designers dedicated to building beautiful, functional, and well-engineered software solutions. We offer very competitive rates as well as fixed-price contracts and welcome inquiries to discuss any custom development / project support needs you may have.

This package is part of our Singulink Libraries collection. Visit https://github.com/Singulink to see our full list of publicly available libraries and other open-source projects.

Installation

The package is available on NuGet - simply install the Singulink.Cryptography.PasswordMatcher package.

Supported Runtimes: Everywhere .NET Standard 2.0 is supported, including:

  • .NET
  • .NET Framework
  • Mono / Xamarin

End-of-life runtime versions that are no longer officially supported are not tested or supported by this library.

Usage

Password Matcher is intended to be used together with a leaked password database such as Have I Been Pwned and rate limiting (as the NIST guidelines recommend) for comprehensive dictionary attack protection. The database covers passwords that are known to be compromised; Password Matcher covers the contextual ones that are easy to predict from your service and the user's details but will never appear in any database.

Checking a password

using Singulink.Cryptography;

ContextualSubject[] subjects = [
    new("Acme Widgets", ContextualSubjectType.Company),
    new("https://www.acmewidgets.com", ContextualSubjectType.Website),
    new("Jane Doe", ContextualSubjectType.Name),
    new("jane.doe@example.com", ContextualSubjectType.Email),
];

var match = PasswordMatchEvaluator.Default.MatchPassword(password, subjects);

if (match is not null)
{
    // Reject the password. match.Values contains the values it was built from, i.e. for "AcmeJane2024!" it
    // would contain ["acme", "jane", "2024", "!"]. match.Items additionally includes the type of each match.
}

A password matches when it is composed entirely of common password words, phrases and values (such as password, iloveyou and qwerty, including common character substitutions like p@55w0rd) or the contextual subjects you provide, in a predictable order, optionally decorated with years, keyboard and keypad sequences, repeated characters and groups, and a few arbitrary digits or symbols (Acme#1, mike2024!!, Welcome@123). The default matchers match about 100 of the most common password words in the most common orders, plus any short combination of those words and decorations.

If a match is returned, you should display a message to the user along the lines of:

Your password is composed entirely of the most common words used in passwords or easily guessed contextual words in a predictable sequence. Suggestion: Add an uncommon word or character sequence to your password to make it less susceptible to attacks.

You can optionally display the matched values to the user so they can see the phrase their password matched.

Contextual subjects

Contextual subjects are values specific to your application or the user that a password should not be built from. Subject values are split into words (on spaces, periods, dashes, underscores, commas, colons, semicolons and @) that can appear in any order, so a name of Jane Doe matches janedoe, doejane, jane and doe. Email subjects ignore their top-level domain and website subjects ignore their protocol, www. prefix, top-level domain and path, so com and www never count as matched words.

Password length

Evaluation cost grows roughly quadratically with password length, so PasswordMatchEvaluator only evaluates passwords up to MaxPasswordLength characters (128 by default) and reports longer passwords as not matched. A password that long made entirely of common words is not a realistic risk, and skipping the check keeps the cost of evaluating adversarial input bounded. The limit can be changed by creating your own evaluator:

var evaluator = new PasswordMatchEvaluator(PasswordMatchersProvider.Default, maxPasswordLength: 64);

Customizing matching

The library is built from composable matchers so the default behavior can be extended or replaced:

  • Custom patterns: Derive from PasswordMatchersProvider and override GetMatchers() to add or change the patterns passwords are checked against. The predefined word lists and decoration matchers in CommonMatchers and the PasswordMatcher.Text(), Sequence(), Any(), Optional(), Repeat(), Permutations(), CharSequence(), FixedDigits(), RepeatedChars(), RepeatedGroups() and AnyChars() factory methods are the building blocks.
  • Custom contextual subject handling: Implement IContextualSubjectMatcherProvider (or derive from ContextualSubjectMatcherProvider) to change how subjects are turned into matchers.
  • Custom matchers: Derive from ValueMatcher to create a matcher that consumes text, or from PasswordMatcher to compose other matchers.

Matchers and evaluators are immutable and safe to share between threads, so the Default instances can be used from anywhere.

Further Reading

The project documentation site has in-depth guides on contextual subjects, match results, customizing the patterns, writing your own matchers and fitting the check into a password policy, along with concept articles on how matching works and what it does and does not protect against. You can also browse the fully documented API there.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net8.0-windows10.0.19041 is compatible.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 83 10/15/2026
0.14.0 266 8/18/2025