using System.Security.Cryptography; using System.Text; namespace FutureMailAPI.Helpers { public interface IPasswordHelper { string HashPassword(string password); bool VerifyPassword(string password, string hash); string HashPassword(string password, string salt); string GenerateSalt(); } public class PasswordHelper : IPasswordHelper { public string HashPassword(string password) { // 生成随机盐值 byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]); // 使用PBKDF2算法生成哈希 var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] hash = pbkdf2.GetBytes(20); // 组合盐值和哈希值 byte[] hashBytes = new byte[36]; Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 20); // 转换为Base64字符串 return Convert.ToBase64String(hashBytes); } public string GenerateSalt() { // 生成随机盐值 byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]); // 转换为Base64字符串 return Convert.ToBase64String(salt); } public string HashPassword(string password, string salt) { // 将Base64盐值转换为字节数组 byte[] saltBytes = Convert.FromBase64String(salt); // 使用PBKDF2算法生成哈希 var pbkdf2 = new Rfc2898DeriveBytes(password, saltBytes, 10000); byte[] hash = pbkdf2.GetBytes(20); // 转换为Base64字符串 return Convert.ToBase64String(hash); } public bool VerifyPassword(string password, string hash) { try { // 从存储的哈希中提取盐值 byte[] hashBytes = Convert.FromBase64String(hash); byte[] salt = new byte[16]; Array.Copy(hashBytes, 0, salt, 0, 16); // 使用相同的盐值计算密码的哈希 var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] computedHash = pbkdf2.GetBytes(20); // 比较两个哈希值 for (int i = 0; i < 20; i++) { if (hashBytes[i + 16] != computedHash[i]) return false; } return true; } catch { return false; } } } }