/// <summary>
 /// Hashes the specified data bytes.
 /// </summary>
 /// <param name="hashData">The hash data.</param>
 /// <returns>
 /// Hashed bytes
 /// </returns>
 protected override byte[] Hash(byte[] hashData)
 {
     using (var sha512 = CryptoAbstraction.CreateSHA512())
     {
         return(sha512.ComputeHash(hashData));
     }
 }
Example #2
0
        /// <summary>
        /// Applies the Bcrypt kdf to derive a key and iv from the passphrase,
        /// the key/iv are returned in the output variable.
        /// Ported from the SSHJ library. https://github.com/hierynomus/sshj
        /// </summary>
        /// <param name="password"></param>
        /// <param name="salt"></param>
        /// <param name="rounds"></param>
        /// <param name="output"></param>
        public void Pbkdf(byte[] password, byte[] salt, int rounds, byte[] output)
        {
            using (var sha512 = CryptoAbstraction.CreateSHA512())
            {
                int    nblocks = (output.Length + 31) / 32;
                byte[] hpass   = sha512.ComputeHash(password);

                byte[] hsalt    = new byte[64];
                byte[] block_b  = new byte[4];
                byte[] outBytes = new byte[32];
                byte[] tmp      = new byte[32];
                for (int block = 1; block <= nblocks; block++)
                {
                    // Block count is in big endian
                    block_b[0] = (byte)((block >> 24) & 0xFF);
                    block_b[1] = (byte)((block >> 16) & 0xFF);
                    block_b[2] = (byte)((block >> 8) & 0xFF);
                    block_b[3] = (byte)(block & 0xFF);

                    hsalt = sha512.ComputeHash(AppendArrays(salt, block_b));
                    Hash(hpass, hsalt, outBytes);
                    Array.Copy(outBytes, 0, tmp, 0, outBytes.Length);

                    for (int round = 1; round < rounds; round++)
                    {
                        hsalt = sha512.ComputeHash(tmp);
                        Hash(hpass, hsalt, tmp);

                        for (int i = 0; i < tmp.Length; i++)
                        {
                            outBytes[i] ^= tmp[i];
                        }
                    }

                    for (int i = 0; i < outBytes.Length; i++)
                    {
                        int idx = i * nblocks + (block - 1);
                        if (idx < output.Length)
                        {
                            output[idx] = outBytes[i];
                        }
                    }
                }
            }
        }