Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class PBKDF2Hash
- {
- public const int SaltByteSize = 24;
- public const int HashByteSize = 20; // to match the size of the PBKDF2-HMAC-SHA-1 hash
- public const int PBKDF2Iterations = 1000;
- public const int IterationIndex = 0;
- public const int SaltIndex = 1;
- public const int PBKDF2Index = 2;
- public static string HashPassword(string password)
- {
- var cryptoProvider = new System.Security.Cryptography.RNGCryptoServiceProvider();
- byte[] salt = new byte[SaltByteSize];
- cryptoProvider.GetBytes(salt);
- var hash = GetPBKDF2Bytes(password, salt, PBKDF2Iterations, HashByteSize);
- return $"{PBKDF2Iterations}:{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
- }
- public static bool ValidatePassword(string password, string correctHash)
- {
- char[] delimiter = { ':' };
- var split = correctHash.Split(delimiter);
- var iterations = Int32.Parse(split[IterationIndex]);
- var salt = Convert.FromBase64String(split[SaltIndex]);
- var hash = Convert.FromBase64String(split[PBKDF2Index]);
- var testHash = GetPBKDF2Bytes(password, salt, iterations, hash.Length);
- return SlowEquals(hash, testHash);
- }
- private static bool SlowEquals(byte[] a, byte[] b)
- {
- var diff = (uint)a.Length ^ (uint)b.Length;
- for (int i = 0; i < a.Length && i < b.Length; i++) diff |= (uint)(a[i] ^ b[i]);
- return diff == 0;
- }
- private static byte[] GetPBKDF2Bytes(string password, byte[] salt, int iterations, int outputBytes)
- {
- var PBKDF2 = new System.Security.Cryptography.Rfc2898DeriveBytes(password, salt);
- PBKDF2.IterationCount = iterations;
- return PBKDF2.GetBytes(outputBytes);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement