Beispiel #1
0
        private static byte[] F(byte[] salt, int iterationCount, int blockIndex, HMAC prf)
        {            
            byte[] U = prf.ComputeHash(Arrays.Concat(salt, Arrays.IntToBytes(blockIndex))); // U_1 = PRF (P, S || INT (i))
            byte[] result = U;

            for(int i=2;i<=iterationCount;i++)
            {
                U = prf.ComputeHash(U);                                                     // U_c = PRF (P, U_{c-1}) .                
                result = Arrays.Xor(result, U);                                             // U_1 \xor U_2 \xor ... \xor U_c
            }

            return result;
        }
		}// DeriveKey()

		internal static void DeriveKey(HMAC keyedHmac, ArraySegment<byte> bufferSegment, ArraySegment<byte> derivedOutput, uint counter = 1)
		{
			int derivedOutputCount = derivedOutput.Count, derivedOutputOffset = derivedOutput.Offset;
			byte[] K_i = null;
			HMAC2 keyedHmac2 = keyedHmac as HMAC2;
			checked
			{
				// Calculate each K_i value and copy the leftmost bits to the output buffer as appropriate.
				for (var counterStruct = new Utils.IntStruct { UintValue = counter }; derivedOutputCount > 0; ++counterStruct.UintValue)
				{
					counterStruct.ToBEBytes(bufferSegment.Array, bufferSegment.Offset); // update the counter within the buffer

					if (keyedHmac2 == null)
					{
						K_i = keyedHmac.ComputeHash(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count);
					}
					else
					{
						keyedHmac2.TransformBlock(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count, null, 0);
						keyedHmac2.TransformFinalBlock(bufferSegment.Array, 0, 0);
						K_i = keyedHmac2.HashInner;
					}

					// copy the leftmost bits of K_i into the output buffer
					int numBytesToCopy = derivedOutputCount > K_i.Length ? K_i.Length : derivedOutputCount;//Math.Min(derivedOutputCount, K_i.Length);
					Utils.BlockCopy(K_i, 0, derivedOutput.Array, derivedOutputOffset, numBytesToCopy);
					derivedOutputOffset += numBytesToCopy;
					derivedOutputCount -= numBytesToCopy;
				}// for
			}// checked
			if (keyedHmac2 == null && K_i != null) Array.Clear(K_i, 0, K_i.Length); /* clean up needed only when HMAC implementation is not HMAC2 */
		}// DeriveKey()
Beispiel #3
0
        public byte[] ComputeHash(byte[] buffer, int offset, int count)
        {
#if WINDOWS_STORE
            MacAlgorithmProvider provider = MacAlgorithmProvider.OpenAlgorithm(algorithmName);

            CryptographicKey hmacKey;
            if (Key != null)
            {
                hmacKey = provider.CreateKey(CryptographicBuffer.CreateFromByteArray(Key));
            }
            else
            {
                hmacKey = provider.CreateKey(CryptographicBuffer.GenerateRandom(provider.MacLength));
            }

            IBuffer hmacValue = CryptographicEngine.Sign(hmacKey, CryptographicBuffer.CreateFromByteArray(buffer));

            byte[] result;
            CryptographicBuffer.CopyToByteArray(hmacValue, out result);

            return(result);
#else
            return(hmac.ComputeHash(buffer, offset, count));
#endif
        }
 public HKDF(Func<HMAC> hmacFactory, byte[] ikm, byte[] salt = null, byte[] context = null)
 {
     hmac = hmacFactory();
     hashLength = hmac.OutputBlockSize;
     hmac.Key = salt ?? new byte[hashLength];
     hmac.Key = hmac.ComputeHash(ikm); // re-keying hmac with PRK
     this.context = context;
     Reset();
 }
Beispiel #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HKDF"/> class.
        /// </summary>
        /// <param name="hmac">The HMAC hash function to use.</param>
        /// <param name="ikm">input keying material.</param>
        /// <param name="salt">optional salt value (a non-secret random value); if not provided, it is set to a string of HMAC.HashSize/8 zeros.</param>
        public HKDF(HMAC hmac, byte[] ikm, byte[] salt = null)
        {
            this.hmac = hmac;
            this.hashLength = hmac.HashSize / 8;

            // now we compute the PRK
            hmac.Key = salt ?? new byte[this.hashLength];
            this.prk = hmac.ComputeHash(ikm);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="inputString"></param>
 /// <param name="key">最长为64位的16进制字符串</param>
 /// <returns></returns>
 public static byte[] GetHMACValue(byte[] inputBuffer, string shaName, byte[] key)
 {
     System.Security.Cryptography.HMAC sha = System.Security.Cryptography.HMAC.Create(shaName);
     if (key != null && key.Length > 0)
     {
         sha.Key = key;
     }
     byte[] hashBuffer = sha.ComputeHash(inputBuffer);
     return(hashBuffer);
 }
		public HKDF(Func<HMAC> hmacFactory, byte[] ikm, byte[] salt = null, byte[] context = null)
		{
			hmac = hmacFactory();
			hashLength = hmac.OutputBlockSize;

			// a malicious implementation of HMAC could conceivably mess up the shared static empty byte arrays, which are still writeable...
			hmac.Key = salt ?? (hashLength == 64 ? emptyArray64 : hashLength == 48 ? emptyArray48 : hashLength == 32 ? emptyArray32 : hashLength == 20 ? emptyArray20 : new byte[hashLength]);
			hmac.Key = hmac.ComputeHash(ikm); // re-keying hmac with PRK
			this.context = context;
			Reset();
		}
        /// <summary>
        /// A function that verifies a HMAC file with a hash algorithm of your choice
        /// </summary>
        /// <param name="data">A byte[] of encrypted message data</param>
        /// <param name="key">A byte[] of the key</param>
        /// <param name="hash">The hash in the header file/the hash provided, that's been hashed with typeOfHash</param>
        /// <param name="hmac">The HMAC algorithm to use</param>
        /// <returns>True if they match, otherwise false</returns>
        public static bool VerifyHmac(byte[] data, byte[] key, byte[] hash, System.Security.Cryptography.HMAC hmac)
        {
            byte[] hashKey;
            hmac.Key = key;

            using (hmac)
            {
                hashKey = hmac.ComputeHash(data);
            }

            return(hash.SequenceEqual(hashKey));
        }
        /// <summary>
        /// Signs a encrypted file and key with a hash algorithm of your choosing. Do not try and verify this yourself, use the VerifyHMAC() func
        /// </summary>
        /// <param name="data">A byte[] of the encrypted message data</param>
        /// <param name="key">A byte[] of the key</param>
        /// <param name="hmac">The HMAC algorithm to use</param>
        /// <returns>A byte[] hash that is the file and key hashed</returns>
        public static byte[] CreateHmac(byte[] data, byte[] key, System.Security.Cryptography.HMAC hmac)
        {
            byte[] hashKey;
            hmac.Key = key;

            using (hmac)
            {
                hashKey = hmac.ComputeHash(data);
            }

            return(hashKey);
        }
        /// <summary>
        /// Signs a encrypted file and key with a hash algorithm of your choosing. Do not try and verify this yourself, use the VerifyHMAC() func
        /// </summary>
        /// <param name="path">A path to the file with the encrypted data</param>
        /// <param name="key">A byte[] of the key</param>
        /// <param name="hmac">The HMAC algorithm to use</param>
        /// <returns>A byte[] hash that is the file and key hashed</returns>
        public static byte[] CreateHmac(string path, byte[] key, System.Security.Cryptography.HMAC hmac)
        {
            byte[] hashKey;
            hmac.Key = key;

            using (var fHandle = new FileStream(path, FileMode.Open))
                using (hmac)
                {
                    hashKey = hmac.ComputeHash(fHandle);
                }

            return(hashKey);
        }
Beispiel #11
0
        // This function is defined as follows:
        // Func (S, i) = HMAC(S || i) | HMAC2(S || i) | ... | HMAC(iterations) (S || i)
        // where i is the block number.
        private byte[] Func()
        {
            byte[] temp = new byte[_salt.Length + sizeof(uint)];
            Buffer.BlockCopy(_salt, 0, temp, 0, _salt.Length);
            Helpers.WriteInt(_block, temp, _salt.Length);

            temp = _hmac.ComputeHash(temp);

            byte[] ret = temp;
            for (int i = 2; i <= _iterations; i++)
            {
                temp = _hmac.ComputeHash(temp);

                for (int j = 0; j < _blockSize; j++)
                {
                    ret[j] ^= temp[j];
                }
            }

            // increment the block count.
            _block++;
            return(ret);
        }
		}// DeriveKey()

		internal static void DeriveKey(HMAC keyedHmac, ArraySegment<byte> bufferSegment, ArraySegment<byte> derivedOutput, uint counter = 1)
		{
			int derivedOutputCount = derivedOutput.Count, derivedOutputOffset = derivedOutput.Offset;
			byte[] K_i = null;
			checked
			{
				// Calculate each K_i value and copy the leftmost bits to the output buffer as appropriate.
				for (var counterStruct = new Utils.IntStruct { UintValue = counter }; derivedOutputCount > 0; ++counterStruct.UintValue)
				{
					counterStruct.ToBEBytes(bufferSegment.Array, bufferSegment.Offset); // update the counter within the buffer
					K_i = keyedHmac.ComputeHash(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count);

					// copy the leftmost bits of K_i into the output buffer
					int numBytesToCopy = Math.Min(derivedOutputCount, K_i.Length);
					Utils.BlockCopy(K_i, 0, derivedOutput.Array, derivedOutputOffset, numBytesToCopy);
					derivedOutputOffset += numBytesToCopy;
					derivedOutputCount -= numBytesToCopy;
				}// for
			}// checked
			if (K_i != null) Array.Clear(K_i, 0, K_i.Length);
		}// DeriveKey()
Beispiel #13
0
        // iterative hash function
        private byte[] Func()
        {
            byte[] INT_block = Utils.GetBigEndianBytes(_block);

            _hmac.TransformBlock(_salt, 0, _salt.Length, _salt, 0);
            _hmac.TransformFinalBlock(INT_block, 0, INT_block.Length);
            byte[] temp = _hmac.Hash;
            _hmac.Initialize();

            byte[] ret = temp;
            for (int i = 2; i <= _iterationCount; i++)
            {
                temp = _hmac.ComputeHash(temp);
                for (int j = 0; j < _blockSize; j++)
                {
                    ret[j] ^= temp[j];
                }
            }

            _block++;
            return(ret);
        }
Beispiel #14
0
		public void CheckA (string testName, HMAC algo, byte[] data, byte[] result)
		{
			byte[] hmac = algo.ComputeHash (data);
			Compare (result, hmac, testName + "a1");
			Compare (result, algo.Hash, testName + "a2");
		}
Beispiel #15
0
        /// <summary>
        /// hmac should be initialized with the secret key
        /// </summary>
        /// <param name="hmac"></param>
        /// <param name="label"></param>
        /// <param name="seed"></param>
        /// <param name="bytesNeeded"></param>
        /// <returns></returns>
        public static byte[] PRF(HMAC hmac, string label, byte[] seed, int bytesNeeded)
        {
            var blockSize = hmac.HashSize / 8;
            var rounds = (bytesNeeded + (blockSize - 1)) / blockSize;

            var labelLen = Encoding.ASCII.GetByteCount(label);
            var a = new byte[labelLen + seed.Length];
            Encoding.ASCII.GetBytes(label, 0, label.Length, a, 0);
            Buffer.BlockCopy(seed, 0, a, labelLen, seed.Length);

            byte[] ret = new byte[rounds * blockSize];
            byte[] input = new byte[blockSize + a.Length];
            Buffer.BlockCopy(a, 0, input, blockSize, a.Length);

            for (var i = 0; i < rounds; i++)
            {
                var aNew = hmac.ComputeHash(a);
                ClearArray(a);
                a = aNew;
                Buffer.BlockCopy(a, 0, input, 0, blockSize);
                byte[] temp = hmac.ComputeHash(input);
                Buffer.BlockCopy(temp, 0, ret, i * blockSize, blockSize);
                ClearArray(temp);
            }
            ClearArray(a);
            ClearArray(input);
            if (bytesNeeded == ret.Length)
                return ret;
            byte[] retTruncated = new byte[bytesNeeded];
            Buffer.BlockCopy(ret, 0, retTruncated, 0, bytesNeeded);
            ClearArray(ret);
            return retTruncated;
        }
Beispiel #16
0
		public void CheckB (string testName, HMAC algo, byte[] data, byte[] result)
		{
			byte[] hmac = algo.ComputeHash (data, 0, data.Length);
			Compare (result, hmac, testName + "b1");
			Compare (result, algo.Hash, testName + "b2");
		}
        // NOTE: This method also exists in Win8 (as BCryptKeyDerivation) and QTD (as DeriveKeySP800_108).
        // However, the QTD implementation is currently incorrect, so we can't depend on it here. The below
        // is a correct implementation. When we take a Win8 dependency, we can call into BCryptKeyDerivation.
        private static byte[] DeriveKeyImpl(HMAC hmac, byte[] label, byte[] context, int keyLengthInBits) {
            // This entire method is checked because according to SP800-108 it is an error
            // for any single operation to result in overflow.
            checked {

                // Make a buffer which is ____ || label || 0x00 || context || [l]_2.
                // We can reuse this buffer during each round.

                int labelLength = (label != null) ? label.Length : 0;
                int contextLength = (context != null) ? context.Length : 0;
                byte[] buffer = new byte[4 /* [i]_2 */ + labelLength /* label */ + 1 /* 0x00 */ + contextLength /* context */ + 4 /* [L]_2 */];

                if (labelLength != 0) {
                    Buffer.BlockCopy(label, 0, buffer, 4, labelLength); // the 4 accounts for the [i]_2 length
                }
                if (contextLength != 0) {
                    Buffer.BlockCopy(context, 0, buffer, 5 + labelLength, contextLength); // the '5 +' accounts for the [i]_2 length, the label, and the 0x00 byte
                }
                WriteUInt32ToByteArrayBigEndian((uint)keyLengthInBits, buffer, 5 + labelLength + contextLength); // the '5 +' accounts for the [i]_2 length, the label, the 0x00 byte, and the context

                // Initialization

                int numBytesWritten = 0;
                int numBytesRemaining = keyLengthInBits / 8;
                byte[] output = new byte[numBytesRemaining];

                // Calculate each K_i value and copy the leftmost bits to the output buffer as appropriate.

                for (uint i = 1; numBytesRemaining > 0; i++) {
                    WriteUInt32ToByteArrayBigEndian(i, buffer, 0); // set the first 32 bits of the buffer to be the current iteration value
                    byte[] K_i = hmac.ComputeHash(buffer);

                    // copy the leftmost bits of K_i into the output buffer
                    int numBytesToCopy = Math.Min(numBytesRemaining, K_i.Length);
                    Buffer.BlockCopy(K_i, 0, output, numBytesWritten, numBytesToCopy);
                    numBytesWritten += numBytesToCopy;
                    numBytesRemaining -= numBytesToCopy;
                }

                // finished
                return output;
            }
        }
        private static byte[] SignAndEncrypt(
            string dataToEncrypt, HMAC hmacAlgorithm, SymmetricAlgorithm encryptionAlgorithm)
        {
            Byte[] rawOtherData = Encoding.UTF8.GetBytes(dataToEncrypt);

            // Compute the hash
            Byte[] hashedData = hmacAlgorithm.ComputeHash(rawOtherData, 0, rawOtherData.Length);

            // Encrypt the data
            Byte[] encryptedData = new Byte[hashedData.Length + rawOtherData.Length];
            Array.Copy(hashedData, encryptedData, hashedData.Length);
            Array.Copy(rawOtherData, 0, encryptedData, hashedData.Length, rawOtherData.Length);
            using (ICryptoTransform transform = encryptionAlgorithm.CreateEncryptor())
            {
                encryptedData =
                    transform.TransformFinalBlock(
                        encryptedData,
                        0,
                        encryptedData.Length);
            }
            return encryptedData;
        }
        /// <summary>
        /// Hashes the counter using the hmac and secretkey
        /// </summary>
        private static byte[] HashCounter(HMAC hmacGenerator, byte[] secretKey, ulong counter)
        {
            hmacGenerator.Key = secretKey;

            //Spec says 8byte, array
            byte[] counterBytes = new byte[COUNTER_LEGNTH];

            //Bit converter may return an arry with less than 8 bytes
            byte[] intermediateBytes = BitConverter.GetBytes(counter);

            //Copy number-bytes into padded buffer.
            Array.Copy(intermediateBytes, counterBytes, counterBytes.Length);

            if (BitConverter.IsLittleEndian)
            {
                counterBytes = counterBytes.Reverse().ToArray();
            }

            return hmacGenerator.ComputeHash(counterBytes);
        }
Beispiel #20
0
		public void CheckC (string testName, HMAC algo, byte[] data, byte[] result)
		{
			using (MemoryStream ms = new MemoryStream (data)) {
				byte[] hmac = algo.ComputeHash (ms);
				Compare (result, hmac, testName + "c1");
				Compare (result, algo.Hash, testName + "c2");
			}
		}
Beispiel #21
0
 private static byte[] A(HMAC hmac, byte[] aMinus1Result)
 {
     return hmac.ComputeHash(aMinus1Result);
 }
        private void HMACSanityCheck(HMAC hmac, params byte[] expected)
        {
            // test_case = 2
            string key = "Jefe";
            byte[] keyBytes = Encoding.ASCII.GetBytes(key);

            string data = "what do ya want for nothing?";
            byte[] dataBytes = Encoding.ASCII.GetBytes(data);

            hmac.Key = keyBytes;
            byte[] digest = hmac.ComputeHash(dataBytes);

            CollectionAssert.AreEqual(expected, digest);
        }
Beispiel #23
0
        // From section 5 of RFC 2246
        // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
        //                        HMAC_hash(secret, A(2) + seed) +
        //                        HMAC_hash(secret, A(3) + seed) + ...
        //   A() is defined as:
        //       A(0) = seed
        //       A(i) = HMAC_hash(secret, A(i-1))
        private static byte[] PHash(HMAC hmac, byte[] seed, int bytesToGenerate)
        {
            using (MemoryStream bytesToHashBuffer = new MemoryStream())
            using (MemoryStream output = new MemoryStream())
            {
                byte[] previousA = seed;

                while (output.Length < bytesToGenerate)
                {
                    bytesToHashBuffer.SetLength(0);

                    byte[] currentA = A(hmac, previousA);
                    bytesToHashBuffer.Write(currentA, 0, currentA.Length);
                    bytesToHashBuffer.Write(seed, 0, seed.Length);

                    byte[] currentBuffer = bytesToHashBuffer.GetBuffer();

                    byte[] currentRoundResult = hmac.ComputeHash(currentBuffer, 0, (int)bytesToHashBuffer.Length);
                    output.Write(currentRoundResult, 0, currentRoundResult.Length);
                    previousA = currentA;
                }

                output.SetLength(bytesToGenerate);

                return output.ToArray();
            }
        }