PwnedClient 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package PwnedClient --version 1.0.1
NuGet\Install-Package PwnedClient -Version 1.0.1
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="PwnedClient" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add PwnedClient --version 1.0.1
#r "nuget: PwnedClient, 1.0.1"
#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 PwnedClient as a Cake Addin
#addin nuget:?package=PwnedClient&version=1.0.1

// Install PwnedClient as a Cake Tool
#tool nuget:?package=PwnedClient&version=1.0.1

PwnedClient

This is a simple client for accessing the Pwned Passwords service offered for free by the amazing Troy Hunt of https://haveibeenpwned.com. If you don't know why you should be using this service then read this blog post from Troy.

If you intend to use this client then please make sure you agree with the Acceptable Use policy and license for the service.

This client uses version 2 of the interface which means that the password is not sent across the wire to perform the check of whether it has been involved in a security breach. It uses a k-Anonymity model, which means that only the first 5 characters of the hashed password are submitted to the service. The reply from the service will be a list of roughly 400 to 600 breached password hashes that match on those 5 characters, and so the caller of the service can then check that list for the presence of the complete password hash.

Constructing the client

There are two constructors available: a default constructor which will spin up its own instance of an HttpClient, and another that allows you to pass your own HttpClient.

public PwnedClient()
public PwnedClient(HttpClient client)

Depending on your requirements, this client provides a number of ways to access the service.

Let the client do the work

Note: the complete password is not sent across the wire to the service. Even if you use a method that requires a complete password it is just used by this client to inform you on whether it has been compromised in a breach.

These methods provide the most convenience and the least information: informing you of whether the provided password has been compromised or not.

Plain or Hashed password

Find out whether a password is listed in a breach dataset

public bool IsCompromised(string password, bool isHashed = false)

e.g.

var pwdChecker = new PwnedClient();
bool isUnsafe = pwdChecker.IsCompromised("p@55w0rd");
bool isUnsafe2 = pwdChecker.IsCompromised("p@55w0rd".ToSha1Hash(), true);
Find out how compromised a password is

Get a count indicating how many breach data sets the password appears in.

public int GetBreachCount(string password, bool isHashed = false)

e.g.

var pwdChecker = new PwnedClient();
var count = pwdChecker.GetBreachCount("p@55w0rd");
var count2 = pwdChecker.GetBreachCount("p@55w0rd".ToSha1Hash(), true);
Plain text password

An explicit method for plain text password checking.

public bool IsCompromisedPlainTextPassword(string password)

e.g.

var pwdChecker = new PwnedClient();
bool isUnsafe = pwdChecker.IsCompromisedPlainTextPassword("p@55w0rd");

An explicit method for getting the breach count of a plain text password

public int GetBreachCountPlainTextPassword(string password)

e.g.

var pwdChecker = new PwnedClient();
var count = pwdChecker.GetBreachCountPlainTextPassword("p@55w0rd");
Hashed password

An explicit method for hashed password checking. You can provide the SHA1 hashed password, or make use of the provided extension method.

public bool IsCompromisedHashedPassword(string hashedPassword)

e.g.

var pwdChecker = new PwnedClient();
bool isUnsafe = pwdChecker.IsCompromisedHashedPassword("p@55w0rd".ToSha1Hash());

An explicit method for getting the breach count of a hashedpassword

public int GetBreachCountHashedPassword(string hashedPassword)

e.g.

var pwdChecker = new PwnedClient();
var count = pwdChecker.GetBreachCountHashedPassword("p@55w0rd".ToSha1Hash());

You do the work

If you want to do your own heavy lifting, in terms of working out whether the password has been breached, you can use the following methods for returning the compromised password hashes that match the first 5 characters of your hashed password. Both methods require a hashed password, and you can provide either a complete hashed password or just the first 5 characters from the hashed password. Even if you provide the complete password only the first 5 characters are sent to the service.

Get a dictionary returned
public Dictionary<string,int> GetMatchesDictionary(string hashedPassword)

This will return a dictionary of all the suffixes of compromised hashed passwords that share the first 5 characters with your submitted hashed password, along with a prevalence count of how many times it appears in the dataset. You can then work out if your hashed password appears in this list, and maybe use the prevalence count to decide whether it is a safe password to use. Personally, any appearance in the breach dataset would be enough to stop me wanting to use that password.

e.g.

var pwdChecker = new PwnedClient();
var password = "password123";
var hashedPassword = password.ToSha1Hash();
var firstFive = hashedPassword.Substring(0, 5);
var suffix = hashedPassword.Substring(5, hashedPassword.Length - 5);
var result = pwdChecker.GetMatchesDictionary(firstFive);
bool isUnsafe = result.ContainsKey(suffix);
Get raw results returned
public string GetMatchesRaw(string hashedPassword)

This will return a string, with each line consisting of the matched suffix and prevalence count separated by a colon :

For example

0018A45C4D1DEF81644B54AB7F969B88D65:1 00D4F6E8FA6EECAD2A3AA415EEC418D38EC:2 011053FD0102E94D6AE2F8B83D76FAF94F6:1 012A7CA357541F0AC487871FEEC1891C49C:2 0136E006E24E7D152139815FB0FC6A50B15:2 ...

You can then use this raw data as you see fit.

e.g.

var pwdChecker = new PwnedClient();
var password = "password123";
var hashedPassword = password.ToSha1Hash();
var firstFive = hashedPassword.Substring(0, 5);
var suffix = hashedPassword.Substring(5, hashedPassword.Length - 5);
var result = this.passwordChecker.GetMatchesRaw(firstFive);
bool isUnsafe = result.Contains(suffix);
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.
  • .NETStandard 2.0

    • No dependencies.

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.3 3,433 3/28/2019
1.0.2 545 3/28/2019
1.0.1 1,430 3/3/2018
1.0.0 860 2/28/2018

v1.0.1 Added new convenience methods