PasswordRulesSharp 2.0.0

dotnet add package PasswordRulesSharp --version 2.0.0                
NuGet\Install-Package PasswordRulesSharp -Version 2.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="PasswordRulesSharp" Version="2.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PasswordRulesSharp --version 2.0.0                
#r "nuget: PasswordRulesSharp, 2.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.
// Install PasswordRulesSharp as a Cake Addin
#addin nuget:?package=PasswordRulesSharp&version=2.0.0

// Install PasswordRulesSharp as a Cake Tool
#tool nuget:?package=PasswordRulesSharp&version=2.0.0                

PasswordRulesSharp

A C# implementation of an Apple-compatible Password Rules syntax

Usage

Building a rule

You an build a rule either from the raw syntax, or with a builder.

From raw syntax

You can use Apple's tool to help create a rule.

For example, let's use minlength: 20; required: lower; required: upper; required: digit; required: [-];. This requires that the password is at least 20 characters wrong, has at least one lower- and uppercase character each, has a digit, and has a hyphen (-);

To instantiate this as a rule, you use Rule.FromString():

const string rawRule = "minlength: 8; required: lower; required: upper; required: digit; required: [-]";

var rule = Rule.FromString(rawRule);
Using the builder

You can create the same rule as above with RuleBuilder:

var rule = new RuleBuilder()
           .MinLength(8)
           .MaxLength(10)
           .RequireLower()
           .RequireUpper()
           .RequireDigit()
           .RequireAnyOf("-")
           .Build();

Validation

With either of the two approaches to assigning rule, you can now take a password and validate whether it matches that rule:

const string samplePassword1 = "Hello2AndSomeMoreText-";

var validator = new PasswordRulesSharp.Validator.Validator(rule);

bool password1IsValid = validator.PasswordIsValid(samplePassword1, out var results1);

This returns true, as the password matches all rules!

Let's try with one that doesn't:

const string samplePassword2 = "Hello1";

bool password2IsValid = validator.PasswordIsValid(samplePassword2, out var results2);

This returns false, of course. You can look at results2 as to why that is: the library found five requirements. Four are CharacterClassRequirements, and the fifth is a MinimumLengthRequirement. The sample password fulfills three of the character class requirements, but it doesn't have a hyphen, so the validator fails that one. Moreover, the password also doesn't meet the minimum length.

This collection of detailed validation failure results is useful if you want to interactively tell the user why their proposed password cannot be used. But if you want prefer something simpler, you can also discard them, and simply look at the boolean result:

bool password2IsValid = validator.PasswordIsValid(samplePassword2, out _);

This is still enough if you just want a yes/no "is it valid" answer.

Generation

This flow is enough if your users want to pick passwords themselves. But you may also prefer for passwords to be generated. For that, instantiate the Generator:

var generator = new PasswordRulesSharp.Generator.Generator(rule);

var newPassword = generator.GeneratePassword();

You may also find it useful to generate a handful of passwords:

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(generator.GeneratePassword());
}

The output will look like:

-0fBAp4q24d-VA9tO2wC
-nA7A6q-o9S4Jo-1SkD1
80piB-N4Mv8q-AxG0-o8
-hY0i6T-5UcI6jNQ7q-f
b-a7B6C-2FuO8rZyv4R-

All generated passwords will match the rules we've specified. As you can see, they're all 20 characters long, and each contain at least one hyphen, one digit, lower-case character, and upper-case character.

Of note:
  • If you pass a minlength below 20, the generated passwords will still be at least 20 characters long, for security reasons. If you want to generate a shorter password, you can achieve that by also specifying a maxlength. For example, minlength: 8; maxlength: 10; required: lower; required: upper; required: digit; required: [-] will yield generated passwords that are 10 characters long.

  • As you can see, there is no logic for the generated passwords to follow a particular pattern. This increases entropy (and therefore security), but "looks" slightly less nice.

References

Apple's docs: https://developer.apple.com/documentation/security/password_autofill/customizing_password_autofill_rules

Apple's validation tool: https://developer.apple.com/password-rules/

A Rust port: https://docs.rs/password-rules-parser/latest/password_rules_parser/

Further reading

There's also https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.passwordoptions, but it is far more limiting. (Someone might write an importer from that format.)

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 was computed.  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. 
.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 (1)

Showing the top 1 NuGet packages that depend on PasswordRulesSharp:

Package Downloads
StepLang.Leap.Common

A library of common components for interacting with LEAP APIs.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0 792 6/23/2023
2.0.0-alpha1 138 2/15/2023
1.2.0 346 2/13/2023
1.1.0 436 10/20/2022
1.0.0-alpha2 191 4/25/2022
1.0.0-alpha1 167 4/21/2022