using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
public static byte[] RandomSalt()
return RandomNumberGenerator.GetBytes(16);
public static byte[] ComputeHash(string password, byte[] salt, int iterations)
return KeyDerivation.Pbkdf2(password, salt, KeyDerivationPrf.HMACSHA512, iterations, 36);
public static bool SlowEquals(byte[] a, byte[] b)
uint diff = (uint)a.Length ^ (uint)b.Length;
for (int i = 0; i < a.Length && i < b.Length; i++)
diff |= (uint)(a[i] ^ b[i]);
public static bool ComparePassword(string password, byte[] salt, int iterations, byte[] savedHash)
return SlowEquals(ComputeHash(password, salt, iterations), savedHash);
public static void Main()
string originalPassword = "P@ssw0rd1";
byte[] salt = RandomSalt();
byte[] computedHash = ComputeHash(originalPassword, salt, iterations);
string testPassword = "1dr0wss@P";
Console.WriteLine("Checking password {0}, is it valid? {1}", originalPassword, ComparePassword(originalPassword, salt, iterations, computedHash));
Console.WriteLine("Checking password {0}, is it valid? {1}", testPassword, ComparePassword(testPassword, salt, iterations, computedHash));