public bool VerifyHashedPassword(byte[] decodedHashedPassword, string providedPassword) { var paddingMode = (PaddingMode)BufferUtil.ReadNetworkByteOrder(decodedHashedPassword, 1); var cipherMode = (CipherMode)BufferUtil.ReadNetworkByteOrder(decodedHashedPassword, 5); var salt = new byte[32]; Buffer.BlockCopy(decodedHashedPassword, 9, salt, 0, salt.Length); var iv = new byte[16]; Buffer.BlockCopy(decodedHashedPassword, 9 + salt.Length, iv, 0, iv.Length); var expectedKey = new byte[decodedHashedPassword.Length - salt.Length - iv.Length - 9]; Buffer.BlockCopy(decodedHashedPassword, 9 + salt.Length + iv.Length, expectedKey, 0, expectedKey.Length); var cipher = Aes.Create(); cipher.KeySize = 256; cipher.Padding = paddingMode; cipher.Mode = cipherMode; cipher.Key = salt; cipher.IV = iv; var decryptor = cipher.CreateDecryptor(); var expectedPasswordBytes = decryptor.TransformFinalBlock(expectedKey, 0, expectedKey.Length); var expectedPassword = Encoding.UTF8.GetString(expectedPasswordBytes); return(providedPassword.Equals(expectedPassword)); }
public bool VerifyHashedPassword(byte[] decodedHashedPassword, string providedPassword) { // Read header information var prf = (KeyDerivationPrf)BufferUtil.ReadNetworkByteOrder(decodedHashedPassword, 1); var iterCount = (int)BufferUtil.ReadNetworkByteOrder(decodedHashedPassword, 5); var saltLength = (int)BufferUtil.ReadNetworkByteOrder(decodedHashedPassword, 9); // Read the salt: must be >= 128 bits if (saltLength < 128 / 8) { return(false); } var salt = new byte[saltLength]; Buffer.BlockCopy(decodedHashedPassword, 13, salt, 0, salt.Length); // Read the subkey (the rest of the payload): must be >= 128 bits var subkeyLength = decodedHashedPassword.Length - 13 - salt.Length; if (subkeyLength < 128 / 8) { return(false); } var expectedSubkey = new byte[subkeyLength]; Buffer.BlockCopy(decodedHashedPassword, 13 + salt.Length, expectedSubkey, 0, expectedSubkey.Length); // Hash the incoming password and verify it var actualSubKey = KeyDerivation.Pbkdf2(providedPassword, salt, prf, iterCount, subkeyLength); return(iterCount > 0 && BufferUtil.ByteArraysEqual(actualSubKey, expectedSubkey)); }