2 using System.Security.Cryptography;
6 public class CryptoUtils
8 public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount)
10 /* Init HMAC state. */
11 using (var hmac = new HMACSHA256(password))
13 int hashLength = hmac.HashSize / 8;
14 if ((hmac.HashSize & 7) != 0)
18 int keyLength = dklen / hashLength;
19 if ((long)dklen > (0xFFFFFFFFL * hashLength) || dklen < 0)
21 throw new ArgumentOutOfRangeException("dklen");
23 if (dklen % hashLength != 0)
27 byte[] extendedkey = new byte[salt.Length + 4];
28 Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length);
29 using (var ms = new System.IO.MemoryStream())
31 /* Iterate through the blocks. */
32 for (int i = 0; i < keyLength; i++)
34 /* Generate INT(i + 1). */
35 extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF);
36 extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF);
37 extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF);
38 extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF);
40 /* Compute U_1 = PRF(P, S || INT(i)). */
41 byte[] u = hmac.ComputeHash(extendedkey);
42 Array.Clear(extendedkey, salt.Length, 4);
46 for (int j = 1; j < iterationCount; j++)
49 u = hmac.ComputeHash(u);
50 for (int k = 0; k < f.Length; k++)
57 /* Copy as many bytes as necessary into memory stream. */
58 ms.Write(f, 0, f.Length);
59 Array.Clear(u, 0, u.Length);
60 Array.Clear(f, 0, f.Length);
64 /* Initialize result array. */
65 byte[] dk = new byte[dklen];
67 /* Read key from memory stream. */
68 ms.Read(dk, 0, dklen);
71 for (long i = 0; i < ms.Length; i++)
75 Array.Clear(extendedkey, 0, extendedkey.Length);