Files
fiscalos/src/FiscalOS.Infra/Authentication/PasswordHasher.cs
T

63 lines
1.5 KiB
C#

namespace FiscalOS.Infra.Authentication;
public sealed class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16;
private const int HashSize = 32;
private const int Iterations = 100_000;
private static readonly HashAlgorithmName HashAlgorithm = HashAlgorithmName.SHA512;
private PasswordHasher()
{
}
public static PasswordHasher New()
{
return new();
}
public static PasswordHasher From(IServiceProvider serviceProvider)
{
return new();
}
public string Hash(string password)
{
var salt = RandomNumberGenerator.GetBytes(SaltSize);
var hash = Rfc2898DeriveBytes.Pbkdf2(
password,
salt,
Iterations,
HashAlgorithm,
HashSize
);
var hashBytes = new byte[SaltSize + HashSize];
Array.Copy(salt, 0, hashBytes, 0, SaltSize);
Array.Copy(hash, 0, hashBytes, SaltSize, HashSize);
return Convert.ToBase64String(hashBytes);
}
public bool Verify(string providedPassword, string hashedPassword)
{
var hashBytes = Convert.FromBase64String(hashedPassword);
var salt = new byte[SaltSize];
Array.Copy(hashBytes, 0, salt, 0, SaltSize);
var storedHash = new byte[HashSize];
Array.Copy(hashBytes, SaltSize, storedHash, 0, HashSize);
var computedHash = Rfc2898DeriveBytes.Pbkdf2(
providedPassword,
salt,
Iterations,
HashAlgorithm,
HashSize
);
return CryptographicOperations.FixedTimeEquals(storedHash, computedHash);
}
}