You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.3 KiB
67 lines
2.3 KiB
using Isopoh.Cryptography.Argon2;
|
|
using Isopoh.Cryptography.SecureArray;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace Hasher
|
|
{
|
|
/// <summary>
|
|
/// A utility class for generating and verifying Argon2 hashes.
|
|
/// </summary>
|
|
public static class Argon2dHasher
|
|
{
|
|
private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create();
|
|
|
|
/// <summary>
|
|
/// Generates an Argon2 hash for the given password and salt.
|
|
/// </summary>
|
|
/// <param name="password">The password to hash.</param>
|
|
/// <param name="salt">A random salt to use for the hash. If null, a new 16-byte salt will be generated.</param>
|
|
/// <returns>The generated Argon2 hash as a string.</returns>
|
|
public static string GenerateArgon2Hash(string password, byte[]? salt)
|
|
{
|
|
if (salt == null)
|
|
{
|
|
salt = new byte[16];
|
|
}
|
|
byte[] pwBytes = Encoding.UTF8.GetBytes(password);
|
|
|
|
// Generate a random salt
|
|
Rng.GetBytes(salt);
|
|
|
|
var config = new Argon2Config
|
|
{
|
|
Type = Argon2Type.DataIndependentAddressing,
|
|
Version = Argon2Version.Nineteen,
|
|
TimeCost = 6,
|
|
Lanes = 3,
|
|
Threads = Environment.ProcessorCount - 1, // higher than "Lanes" doesn't help (or hurt)
|
|
Password = pwBytes,
|
|
Salt = salt,
|
|
};
|
|
|
|
var argon2 = new Argon2(config);
|
|
|
|
string hashString;
|
|
using(SecureArray<byte> hashA = argon2.Hash())
|
|
{
|
|
hashString = config.EncodeString(hashA.Buffer);
|
|
}
|
|
return hashString;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies that a given password matches an Argon2 hash.
|
|
/// </summary>
|
|
/// <param name="password">The password to check.</param>
|
|
/// <param name="hash">The Argon2 hash to check against.</param>
|
|
/// <returns>True if the password matches the hash, false otherwise.</returns>
|
|
public static bool VerifyArgon2Hash(string password, string hash)
|
|
{
|
|
byte[] pwBytes = Encoding.UTF8.GetBytes(password);
|
|
var valid = Argon2.Verify(hash, pwBytes);
|
|
return valid;
|
|
}
|
|
}
|
|
}
|
|
|
|
|