using System; using System.Security.Cryptography; namespace SNote.Server.Security; public static class PasswordHasher { private const int SaltSize = 16; // 128 bit private const int KeySize = 32; // 256 bit private const int Iterations = 10000; public static string HashPassword(string password) { using var algorithm = new Rfc2898DeriveBytes(password, SaltSize, Iterations, HashAlgorithmName.SHA256); var key = Convert.ToBase64String(algorithm.GetBytes(KeySize)); var salt = Convert.ToBase64String(algorithm.Salt); return $"{Iterations}.{salt}.{key}"; } public static bool VerifyPassword(string hash, string password) { var parts = hash.Split('.', 3); if (parts.Length != 3) return false; var iterations = int.Parse(parts[0]); var salt = Convert.FromBase64String(parts[1]); var key = Convert.FromBase64String(parts[2]); using var algorithm = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256); var keyToCheck = algorithm.GetBytes(KeySize); return CryptographicOperations.FixedTimeEquals(key, keyToCheck); } }