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.
 
 
 
 
 
 
PortfolioLink/backend/Hasher.cs

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;
}
}
}