Exemplo n.º 1
0
        /// <summary>
        /// Returns an IV that's based solely on the contents of a buffer; useful for generating
        /// predictable IVs for ciphertexts that need to be cached. The output value is only
        /// appropriate for use as an IV and must not be used for any other purpose.
        /// </summary>
        /// <remarks>This method uses an iterated unkeyed SHA256 to calculate the IV.</remarks>
        /// <param name="buffer">The input buffer over which to calculate the IV.</param>
        /// <param name="ivBitLength">The requested length (in bits) of the IV to generate.</param>
        /// <returns>The calculated IV.</returns>
        public static byte[] CreatePredictableIV(byte[] buffer, int ivBitLength)
        {
            // Algorithm:
            // T_0 = SHA256(buffer)
            // T_n = SHA256(T_{n-1})
            // output = T_0 || T_1 || ... || T_n (as many blocks as necessary to reach ivBitLength)

            byte[] output         = new byte[ivBitLength / 8];
            int    bytesCopied    = 0;
            int    bytesRemaining = output.Length;

            using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256())
            {
                while (bytesRemaining > 0)
                {
                    byte[] hashed = sha256.ComputeHash(buffer);

                    int bytesToCopy = Math.Min(bytesRemaining, hashed.Length);
                    Buffer.BlockCopy(hashed, 0, output, bytesCopied, bytesToCopy);

                    bytesCopied    += bytesToCopy;
                    bytesRemaining -= bytesToCopy;

                    buffer = hashed; // next iteration (if it occurs) will operate over the block just hashed
                }
            }

            return(output);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Computes the SHA256 hash of a given segment in a buffer.
 /// </summary>
 /// <param name="buffer">The buffer over which to compute the hash.</param>
 /// <param name="offset">The offset at which to begin computing the hash.</param>
 /// <param name="count">The number of bytes in the buffer to include in the hash.</param>
 /// <returns>The binary hash (32 bytes) of the buffer segment.</returns>
 public static byte[] ComputeSHA256Hash(byte[] buffer, int offset, int count)
 {
     using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256())
     {
         return(sha256.ComputeHash(buffer, offset, count));
     }
 }