2 * Novacoin classes library
3 * Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 using System.Security.Cryptography;
24 public class CryptoUtils
26 public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount)
28 /* Init HMAC state. */
29 using (var hmac = new HMACSHA256(password))
31 int hashLength = hmac.HashSize / 8;
32 if ((hmac.HashSize & 7) != 0)
36 int keyLength = dklen / hashLength;
37 if (dklen > (0xFFFFFFFFL * hashLength) || dklen < 0)
39 throw new ArgumentOutOfRangeException("dklen");
41 if (dklen % hashLength != 0)
45 var extendedkey = new byte[salt.Length + 4];
46 Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length);
47 using (var ms = new System.IO.MemoryStream())
49 /* Iterate through the blocks. */
50 for (int i = 0; i < keyLength; i++)
52 /* Generate INT(i + 1). */
53 extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF);
54 extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF);
55 extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF);
56 extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF);
58 /* Compute U_1 = PRF(P, S || INT(i)). */
59 var u = hmac.ComputeHash(extendedkey);
60 Array.Clear(extendedkey, salt.Length, 4);
64 for (int j = 1; j < iterationCount; j++)
67 u = hmac.ComputeHash(u);
68 for (int k = 0; k < f.Length; k++)
75 /* Copy as many bytes as necessary into memory stream. */
76 ms.Write(f, 0, f.Length);
77 Array.Clear(u, 0, u.Length);
78 Array.Clear(f, 0, f.Length);
82 /* Initialize result array. */
83 var dk = new byte[dklen];
85 /* Read key from memory stream. */
86 ms.Read(dk, 0, dklen);
89 for (long i = 0; i < ms.Length; i++)
93 Array.Clear(extendedkey, 0, extendedkey.Length);