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
<PackageReference Include="Singulink.Cryptography.PasswordMatcher" Version="1.0.0" />
<PackageVersion Include="Singulink.Cryptography.PasswordMatcher" Version="1.0.0" />
<PackageReference Include="Singulink.Cryptography.PasswordMatcher" />
paket add Singulink.Cryptography.PasswordMatcher --version 1.0.0
#r "nuget: Singulink.Cryptography.PasswordMatcher, 1.0.0"
#:package Singulink.Cryptography.PasswordMatcher@1.0.0
#addin nuget:?package=Singulink.Cryptography.PasswordMatcher&version=1.0.0
#tool nuget:?package=Singulink.Cryptography.PasswordMatcher&version=1.0.0
Singulink.Cryptography.PasswordMatcher
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.
About Singulink
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
PasswordMatchersProviderand overrideGetMatchers()to add or change the patterns passwords are checked against. The predefined word lists and decoration matchers inCommonMatchersand thePasswordMatcher.Text(),Sequence(),Any(),Optional(),Repeat(),Permutations(),CharSequence(),FixedDigits(),RepeatedChars(),RepeatedGroups()andAnyChars()factory methods are the building blocks. - Custom contextual subject handling: Implement
IContextualSubjectMatcherProvider(or derive fromContextualSubjectMatcherProvider) to change how subjects are turned into matchers. - Custom matchers: Derive from
ValueMatcherto create a matcher that consumes text, or fromPasswordMatcherto 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.
Related Projects:
- Singulink.Cryptography.PasswordHasher: Upgradable hash algorithm password management library.
- Singulink.Cryptography.Pwned: Pwned client/server implementation for self-hosting a pwned password service.
| Product | Versions 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. |
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 6.0.0)
- Singulink.Enums (>= 3.0.0)
- System.Collections.Immutable (>= 10.0.12)
- System.Memory (>= 4.6.3)
-
net8.0
- Singulink.Enums (>= 3.0.0)
- System.Collections.Immutable (>= 10.0.12)
-
net8.0-windows10.0.19041
- Singulink.Enums (>= 3.0.0)
- System.Collections.Immutable (>= 10.0.12)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.