using System.Text; using System.Security.Cryptography; using Microsoft.AspNetCore.Cryptography.KeyDerivation; namespace HashService { public interface IHashService { (string, string) CreateSaltedHash(string value); bool ValidateHash(string value, string salt, string hash); } public class HashService : IHashService { private string CreateSalt() { byte[] randomBytes = new byte[128 / 8]; using (var generator = RandomNumberGenerator.Create()) { generator.GetBytes(randomBytes); return Convert.ToBase64String(randomBytes); } } private string CreateHash(string value, string salt) { var valueBytes = KeyDerivation.Pbkdf2( password: value, salt: Encoding.UTF8.GetBytes(salt), prf: KeyDerivationPrf.HMACSHA512, iterationCount: 10000, numBytesRequested: 256 / 8); return Convert.ToBase64String(valueBytes); } public (string, string) CreateSaltedHash(string value) { var salt = CreateSalt(); var hash = CreateHash(value, salt); return (salt, hash); } public bool ValidateHash(string value, string salt, string hash) => CreateHash(value, salt) == hash; } }