LingAdmin/Backend/LingAdmin.API/Services/PasswordHasher.cs

44 lines
1.4 KiB
C#
Raw Normal View History

2026-04-16 18:13:06 +08:00
using System.Security.Cryptography;
namespace LingAdmin.API.Services;
public class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
private const int Iterations = 10000;
private static readonly HashAlgorithmName Algorithm = HashAlgorithmName.SHA256;
public string HashPassword(string password)
{
var salt = RandomNumberGenerator.GetBytes(SaltSize);
var hash = Rfc2898DeriveBytes.Pbkdf2(password, salt, Iterations, Algorithm, KeySize);
// Combine salt and hash
var result = new byte[SaltSize + KeySize];
Buffer.BlockCopy(salt, 0, result, 0, SaltSize);
Buffer.BlockCopy(hash, 0, result, SaltSize, KeySize);
return Convert.ToBase64String(result);
}
public bool VerifyPassword(string password, string passwordHash)
{
var hashBytes = Convert.FromBase64String(passwordHash);
// Extract salt
var salt = new byte[SaltSize];
Buffer.BlockCopy(hashBytes, 0, salt, 0, SaltSize);
// Extract hash
var hash = new byte[KeySize];
Buffer.BlockCopy(hashBytes, SaltSize, hash, 0, KeySize);
// Compute hash with the extracted salt
var computedHash = Rfc2898DeriveBytes.Pbkdf2(password, salt, Iterations, Algorithm, KeySize);
// Compare hashes
return CryptographicOperations.FixedTimeEquals(hash, computedHash);
}
}