63 lines
1.5 KiB
C#
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);
|
|
}
|
|
} |