Isopoh.Cryptography.Argon2
2.0.0
dotnet add package Isopoh.Cryptography.Argon2 --version 2.0.0
NuGet\Install-Package Isopoh.Cryptography.Argon2 -Version 2.0.0
<PackageReference Include="Isopoh.Cryptography.Argon2" Version="2.0.0" />
paket add Isopoh.Cryptography.Argon2 --version 2.0.0
#r "nuget: Isopoh.Cryptography.Argon2, 2.0.0"
// Install Isopoh.Cryptography.Argon2 as a Cake Addin #addin nuget:?package=Isopoh.Cryptography.Argon2&version=2.0.0 // Install Isopoh.Cryptography.Argon2 as a Cake Tool #tool nuget:?package=Isopoh.Cryptography.Argon2&version=2.0.0
FULLY MANAGED .NET CORE ARGON2 IMPLEMENTATION
INSTALL | USAGE | API | AUTHOR | LICENSE
Argon2 is a hash generator optimized to produce hashes suitable for credential storage, key derivation, or other situations requiring a cryptographically secure password hash. Argon2 was the winner of the 2015 Password Hashing Competition.
This fully managed implementation of Argon2 runs in .NET Core, .NET Framework, or WebAssembly (via Blazor or Uno Platform).
Standard Argon2 Hashing:
var password = "password1";
var passwordHash = Argon2.Hash(password);
Argon2 Verification:
if (Argon2.Verify(passwordHash, password))
{
// do stuff
}
All Argon2 options available for your hashing needs...
MOTIVATION
The Argon2 reference implementation is available from https://github.com/p-h-c/phc-winner-argon2 and, indeed, the C# code in this repository was based upon that implementation but that implementation is in C. Building a C# wrapper around the C implementation is possible but adds complexity.
This 100% managed-code library allows you to use the Argon2 hash in any .NET (including Blazor) application without added complexity.
GETTING STARTED
This requires a .NET environment and runs on Windows, Linux, MacOS, and WebAssembly (via Blazor).
INSTALLATION
NUGET
The recommended way to get started is by use the NuGet package:
Install-Package Isopoh.Cryptography.Argon2
from https://www.nuget.org/packages/Isopoh.Cryptography.Argon2.
This project uses SourceLink so you should be able to step into the source code for debugging even when just adding the NuGet package as a dependency.
CLONE
You can also, of course, go old-school and clone the repository and link use the .csproj files directly:
git clone https://github.com/mheyman/Isopoh.Cryptography.Argon2.git
then add the ProjectReference
lines to your .csproj to reference
...Isopoh.Cryptography.SecureArray\Isopoh.Cryptography.SecureArray.csproj
,
...Isopoh.Cryptography.Blake2b\Isopoh.Cryptography.Blake2b.csproj
, and
...Isopoh.Cryptography.Argon2\Isopoh.Cryptography.Argon2.csproj
. For example:
<ItemGroup>
<ProjectReference Include="..\..\..\Isopoh.Cryptography.Argon2\Isopoh.Cryptography.SecureArray\Isopoh.Cryptography.SecureArray.csproj" />
</ItemGroup>
USAGE
Using the defaults:
var password = "password1";
var passwordHash = Argon2.Hash(password);
if (Argon2.Verify(passwordHash, password))
{
// do stuff
}
Setting everything:
var password = "password1";
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
byte[] salt = new byte[16];
// somewhere in the class definition:
// private static readonly RandomNumberGenerator Rng =
// System.Security.Cryptography.RandomNumberGenerator.Create();
Rng.GetBytes(salt);
var config = new Argon2Config
{
Type = Argon2Type.DataIndependentAddressing,
Version = Argon2Version.Nineteen,
TimeCost = 10,
MemoryCost = 32768,
Lanes = 5,
Threads = Environment.ProcessorCount, // higher than "Lanes" doesn't help (or hurt)
Password = passwordBytes,
Salt = salt, // >= 8 bytes if not null
Secret = secret, // from somewhere
AssociatedData = associatedData, // from somewhere
HashLength = 20 // >= 4
};
var argon2A = new Argon2(config);
string hashString;
using(SecureArray<byte> hashA = argon2A.Hash())
{
hashString = config.EncodeString(hashA.Buffer);
}
//
// Now pretend "passwordBytes" is what just came in and that it must be
// verified against the known "hashString".
//
// Note setting "Threads" to different values doesn't effect the result,
// just the time it takes to get the result.
//
var configOfPasswordToVerify = new Argon2Config { Password = passwordBytes, Threads = 1 };
SecureArray<byte> hashB = null;
try
{
if (configOfPasswordToVerify.DecodeString(hashString, out hashB) && hashB != null)
{
var argon2ToVerify = new Argon2(configOfPasswordToVerify);
using(var hashToVerify = argon2ToVerify.Hash())
{
if (Argon2.FixedTimeEquals(hashB, hashToVerify))
{
// verified
}
}
}
}
finally
{
hashB?.Dispose();
}
//
// Or, more simply (setting "Threads" to "5")
//
if (Argon2.Verify(hashString, passwordBytes, 5))
{
// verified
}
API
The full API is at https://mheyman.github.io/Isopoh.Cryptography.Argon2.
In particular, the various options for Argon2 hashing can be found in
Argon2Config
and used with Argon2.Hash().
There are other Argon2.Hash()
convenience calls available there as well.
If you are only interested in Blake2b, the underlying hash used in Argon2, you can go to the Blake2b.ComputeHash() calls.
Also, there is SecureArray<T>. The SecureArray
takes a SecureArrayCall
which is a class that has three Func<>
properties, one to
LockMemory,
one to
UnlockMemory,
and one to ZeroMemory.
You can easily create your own SecureArrayCall
to lock/unlock/zero or perhaps
to log secure memory actions.
JUST WHAT IS THIS "SecureArray"?
You can think of the SecureArray
sort of like you would think of
SecureString
except that SecureString
does crypto (usually -
encryption isn't supported everywhere)
to protect its sensitive data and has windows of vulnerability when it
decrypts the string for use. SecureArray
protects its data by locking the
data into RAM to keep it from swapping to disk and also zeroing the buffer when
disposed. So, unlike SecureString
, any process with access to your process's
memory will be able to read the data in your SecureArray
, but you do not
have to worry about your data persisting anywhere or multiple copies of your
data floating around RAM due to C#'s memory management.
Because it locks the memory into RAM (and at a non-movable-by-the-garbage-collector location), you need to use it as infrequently as possible and for as short a time as possible. RAM secured this way puts stress on the computer as a whole by denying physical RAM for other processes and puts stress on your particular executable by denying freedom to the garbage collector to reduce fragmentation as needed for best performance.
Note: when using SecureArray in the browser (for example, under Blazor or UnoPlatform), the memory cannot be locked into RAM so SecureArray does its best effort to protect the data by zeroing the buffer when it is disposed.
Note similarly: when using SecureArray in a Universal Windows Platform (UWP)
application, I have yet to figure out how to use the supposedly available
VirtualAllocFromApp()
system call to lock memory into RAM so SecureArray does
its best effort to protect the data by zeroing the buffer when it is disposed.
Always dispose of your SecureArray
s.
BLAKE2B PEDIGREE
Argon2 uses Blake2b as a cryptographic building block. This code uses the
C# implementation of Blake2 modified from https://github.com/BLAKE2.
The main modification is that the Blake2 here uses SecureArray<T>. The SecureArray
takes a SecureArrayCall
to protect potentially sensitive data. Most other modifications are
strictly cosmetic.
As part of this Blake2b port, an effort was made to speed Blake2b by using techniques like unrolling and using raw buffers in unsafe code. It turns out the CLR optimizes plain code better than unrolled/unsafe code and the original always ran faster. At some point I may try a port to System.Numerics.Vector<T>...
API GENERATION
The API Documentation at https://mheyman.github.io/Isopoh.Cryptography.Argon2 gets generated automatically upon build. This happens via a dummy C# "Doc" project that uses the DocFx NuGet package to produce the API documentation.
AUTHOR
ACKNOWLEDGMENTS
List of people and project that inspired creation of this one:
- The many contributers of the Argon2 repository
- and the cryptographers responsible for creating and testing that algorithm
- @CodesInChaos for the fully managed Blake2b implementation here
- @PurpleBooth for his readme template posted here
LICENSE
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Isopoh.Cryptography.Argon2</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://github.com/mheyman/Isopoh.Cryptography.Argon2" property="cc:attributionName" rel="cc:attributionURL">Michael Heyman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
PRODUCTION STATUS & SUPPORT
You should be aware that this project is supported solely by me and provided as is.
Go back to the project description
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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 is compatible. |
.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. |
-
.NETCoreApp 3.1
- Isopoh.Cryptography.Blake2b (>= 2.0.0)
- Isopoh.Cryptography.SecureArray (>= 2.0.0)
-
.NETStandard 2.0
- Isopoh.Cryptography.Blake2b (>= 2.0.0)
- Isopoh.Cryptography.SecureArray (>= 2.0.0)
-
net6.0
- Isopoh.Cryptography.Blake2b (>= 2.0.0)
- Isopoh.Cryptography.SecureArray (>= 2.0.0)
-
net7.0
- Isopoh.Cryptography.Blake2b (>= 2.0.0)
- Isopoh.Cryptography.SecureArray (>= 2.0.0)
NuGet packages (23)
Showing the top 5 NuGet packages that depend on Isopoh.Cryptography.Argon2:
Package | Downloads |
---|---|
Peachpie.Library
Peachpie PHP language library functions. |
|
NetSFTPLibrary
Library for performing SFTP (FTP over SSH). Features include Automatic Reconnect & Resume, Proxy Support, Public & Private Keys, ZLIB Compression, Directory Synchronization, SCP, Shell, Port Forwarding (Tunneling), FIPS Compliant Mode, and more. |
|
FluffySpoon.Security.Hashing
Provides mechanisms for hashing. |
|
FFCEI.Microservices
A free library for ASP.NET Core 6+ Microservices development, with Model, Model Repository, Entity Framework Core and common Web Api features like CORS, Json serialization fixes, Swagger generation, JWT Authentication for simple and objective microservices development |
|
Vlingo.Xoom.Common
This is a very early stage release of the vlingo platform. The vlingo-net-common project consists of some tools that are used across various other vlingo-net projects. |
GitHub repositories (3)
Showing the top 3 popular GitHub repositories that depend on Isopoh.Cryptography.Argon2:
Repository | Stars |
---|---|
peachpiecompiler/peachpie
PeachPie - the PHP compiler and runtime for .NET and .NET Core
|
|
AniAPI-Team/AniAPI
Core behind AniAPI HTTP Rest APIs.
|
|
johnstaveley/SecurityEssentials
Raise your baseline in security by using this as your template instead of default Mvc project. Keep your app secure by continuously applying Security rules
|
Version | Downloads | Last updated |
---|---|---|
2.0.0 | 287,039 | 8/17/2023 |
1.1.12 | 373,505 | 5/22/2022 |
1.1.11 | 67,908 | 12/12/2021 |
1.1.10 | 491,110 | 11/18/2020 |
1.1.9 | 20,731 | 10/2/2020 |
1.1.8 | 51,727 | 7/26/2020 |
1.1.7 | 630 | 7/26/2020 |
1.1.6 | 714 | 7/25/2020 |
1.1.5 | 621 | 7/25/2020 |
1.1.4 | 5,258 | 7/5/2020 |
1.1.3 | 94,375 | 10/27/2019 |
1.1.2 | 116,261 | 5/14/2019 |
1.1.1 | 2,264 | 2/16/2019 |
1.1.0 | 752 | 2/16/2019 |
1.0.10 | 1,341 | 2/10/2019 |
1.0.9 | 719 | 2/10/2019 |
1.0.8 | 87,176 | 3/11/2018 |
1.0.7 | 1,047 | 3/11/2018 |
1.0.6 | 11,955 | 1/13/2018 |
1.0.5 | 1,208 | 10/29/2017 |
1.0.4 | 1,069 | 9/23/2017 |
1.0.3 | 1,001 | 9/10/2017 |
1.0.2 | 1,115 | 8/31/2017 |
1.0.1 | 1,581 | 3/8/2017 |
1.0.0 | 2,421 | 7/31/2016 |
Hash string no longer has $data field. Proper hash on >64-byte but not multiple of 64-byte.