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()
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(); }
/// <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); }
// 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()
// 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); }
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"); }
/// <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; }
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); }
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"); } }
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); }
// 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(); } }