public HMACBuildInAdapter(HMAC a_hmac, int a_blockSize) : base(a_hmac.HashSize / 8, a_blockSize) { Debug.Assert(a_hmac != null); m_hmac = a_hmac; }
/// <summary> /// Initializes a new instance of the NistSP800108DeriveBytes using specified algorithm. /// </summary> /// <param name="masterKey">The master key to derive from.</param> /// <param name="label">The primary purpose string.</param> /// <param name="context">The secondary purpose strings.</param> /// <param name="pseudoRandomFunction">The HMAC function to use as PRF.</param> public NistSP800108DeriveBytes(byte[] masterKey, string label, string[] context, HMAC pseudoRandomFunction) { // Validate arguments if (masterKey == null) throw new ArgumentNullException("masterKey"); if (masterKey.Length == 0) throw new ArgumentException("The argument cannot be empty.", "masterKey"); if (label == null) throw new ArgumentNullException("label"); if (string.IsNullOrWhiteSpace(label)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "label"); if (pseudoRandomFunction == null) throw new ArgumentNullException("pseudoRandomFunction"); // Setup internal parameters this.pseudoRandomFunction = pseudoRandomFunction; this.pseudoRandomFunction.Key = masterKey; // Convert label and context to byte arrays var safeUtf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); this.labelBytes = safeUtf8.GetBytes(label); if(context== null || context.Length > 0) { this.contextBytes = new byte[0]; } else { using (MemoryStream stream = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(stream, safeUtf8)) { foreach (string item in context) { if (string.IsNullOrWhiteSpace(item)) continue; // Skip empty context item writer.Write(item); } this.contextBytes = stream.ToArray(); } } }
}// 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 MerchantTerminal(string GatewayID, string TerminalPassword, string HMACKeyID, string HMACKey) { mGatewayID = GatewayID; mTerminalPassword = TerminalPassword; mHMACKeyID = HMACKeyID; mHMACEncryptionClient = new HMACSHA1(Encoding.UTF8.GetBytes(HMACKey)); }
static byte[] Compute_PHash(int bytes, byte[][] seeds, HMAC hmac, int blockSize) { int blocks = (bytes / blockSize) + (bytes % blockSize == 0 ? 0 : 1); byte[] ret = new byte[blockSize * blocks]; byte[] prev = null; for (int i = 0; i < blocks; i++) { hmac.Initialize (); if (prev == null) { for (int q = 0; q < seeds.Length; q ++) hmac.TransformBlock (seeds[q], 0, seeds[q].Length, seeds[q], 0); } else { hmac.TransformBlock (prev, 0, prev.Length, prev, 0); } hmac.TransformFinalBlock (Utility.EmptyByteArray, 0, 0); prev = hmac.Hash; hmac.Initialize (); hmac.TransformBlock (prev, 0, prev.Length, prev, 0); for (int q = 0; q < seeds.Length; q++) hmac.TransformBlock (seeds[q], 0, seeds[q].Length, seeds[q], 0); hmac.TransformFinalBlock (Utility.EmptyByteArray, 0, 0); for (int q = 0; q < blockSize; q++) ret[i * blockSize + q] = hmac.Hash[q]; } return ret; }
//something about mode needing to be const or default public Pbkdf2Advanced(string password, int saltSize, uint iterations /*1000*/, Type mode /* = typeof(HMACSHA256)*/) { if (saltSize < 0) { throw new ArgumentOutOfRangeException(nameof(saltSize)); } var salt = new byte[saltSize]; using (var rng = new RNGCryptoServiceProvider()) rng.GetBytes(salt); _salt = salt; _iterations = iterations; if (mode.IsSubclassOf(typeof(System.Security.Cryptography.HMAC))) { _hmac = (System.Security.Cryptography.HMAC)Activator.CreateInstance(mode, new UTF8Encoding(false).GetBytes(password)); } else { throw new ArgumentException("You did not supply a valid Hashing algorithm"); } Reset(); }
public void EnableReceiveCipher(ICryptoTransform decryptor, HMAC recvHMAC) { _decryptor = decryptor; _recvHMAC = recvHMAC; if (_recordType == RecordState.PlainText) _recordType = RecordState.CipherTextReceiveOnly; else _recordType = RecordState.CipherText; }
public void Dispose() { if (!disposed) { hmac.Dispose(); hmac = null; disposed = true; } }
}//ctor /// <summary> /// ctor /// </summary> /// <param name="password"></param> /// <param name="salt"></param> /// <param name="iterations"></param> public PBKDF2(Func<HMAC> hmacFactory, byte[] password, byte[] salt, int iterations) { this.Salt = salt; this.IterationCount = iterations; this.hmac = hmacFactory(); this.hmac.Key = password; this.BlockSize = hmac.HashSize / 8; this.Initialize(); }//ctor
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); }
private static void GetAlgorithmParameters( string algorithm, byte[] key, out byte[] aes_key, out byte[] hmac_key, out HMAC hmac ) { switch ( algorithm ) { case Aes128CbcHmacSha256.AlgorithmName: { if ( ( key.Length << 3 ) < 256 ) throw new CryptographicException( string.Format( CultureInfo.CurrentCulture, "{0} key length in bits {1} < 256", algorithm, key.Length << 3 ) ); hmac_key = new byte[128 >> 3]; aes_key = new byte[128 >> 3]; Array.Copy( key, hmac_key, 128 >> 3 ); Array.Copy( key, 128 >> 3, aes_key, 0, 128 >> 3 ); hmac = new HMACSHA256( hmac_key ); break; } case Aes192CbcHmacSha384.AlgorithmName: { if ( ( key.Length << 3 ) < 384 ) throw new CryptographicException( string.Format( CultureInfo.CurrentCulture, "{0} key length in bits {1} < 384", algorithm, key.Length << 3 ) ); hmac_key = new byte[192 >> 3]; aes_key = new byte[192 >> 3]; Array.Copy( key, hmac_key, 192 >> 3 ); Array.Copy( key, 192 >> 3, aes_key, 0, 192 >> 3 ); hmac = new HMACSHA384( hmac_key ); break; } case Aes256CbcHmacSha512.AlgorithmName: { if ( ( key.Length << 3 ) < 512 ) throw new CryptographicException( string.Format( CultureInfo.CurrentCulture, "{0} key length in bits {1} < 512", algorithm, key.Length << 3 ) ); hmac_key = new byte[256 >> 3]; aes_key = new byte[256 >> 3]; Array.Copy( key, hmac_key, 256 >> 3 ); Array.Copy( key, 256 >> 3, aes_key, 0, 256 >> 3 ); hmac = new HMACSHA512( hmac_key ); break; } default: { throw new CryptographicException( string.Format( CultureInfo.CurrentCulture, "Unsupported algorithm: {0}", algorithm ) ); } } }
public void init(byte[] key) { if (key.Length > BSIZE) { byte[] tmp = new byte[BSIZE]; Array.Copy(key, 0, tmp, 0, BSIZE); key = tmp; } mac = new SSC.HMACSHA1(key); cs = new SSC.CryptoStream(Stream.Null,mac,SSC.CryptoStreamMode.Write); }
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(); }
public void init(byte[] key) { if (key.Length > ORIGBSIZE) { byte[] tmp = new byte[ORIGBSIZE]; Array.Copy(key, 0, tmp, 0, ORIGBSIZE); key = tmp; } mac = new SSC.HMACMD5(key); cs = new SSC.CryptoStream(Stream.Null, mac, SSC.CryptoStreamMode.Write); }
public MainForm() { InitializeComponent(); cmbProviders.Items.AddRange(cryptoServices); openFileDialog1.FileOk += openFileDialog1_FileOk; Load += MainForm_Load; FormClosing += MainForm_FormClosing; Application.ApplicationExit += Application_ApplicationExit; m_macAlgorithm = new HMACMD5(); m_rsaHelper = new RSASignHelper(); }
/// <summary> /// Creates new instance. /// </summary> /// <param name="algorithm">HMAC algorithm to use.</param> /// <param name="input">The input used to derive the key.</param> /// <param name="salt">The key salt used to derive the key.</param> /// <param name="iterations">The number of iterations for the operation.</param> /// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception> public PBKDF2(HMAC algorithm, Byte[] input, Byte[] salt, int iterations) { if (algorithm == null) { throw new ArgumentNullException("algorithm", "Algorithm cannot be null."); } if (salt == null) { throw new ArgumentNullException("salt", "Salt cannot be null."); } if (input == null) { throw new ArgumentNullException("input", "input cannot be null."); } this.Algorithm = algorithm; this.Algorithm.Key = input; this.Salt = salt; this.Iterations = iterations; this.BlockSize = 16;// this.Algorithm.HashSize / 8; this.BufferBytes = new byte[this.BlockSize]; }
/// <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); }
public void init(byte[] key) { if (key.Length > 20) { byte[] tmp = new byte[20]; Array.Copy(key, 0, tmp, 0, 20); key = tmp; } mentalis_mac = new System.Security.Cryptography.HMACSHA1(key); cs = new CryptoStream(Stream.Null, mentalis_mac, CryptoStreamMode.Write); }
/// <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> /// Get the hash algorithm and hmac algorithm for V2. /// </summary> /// <param name="hashAlgo">The hash algorithm value</param> /// <returns>The hash algorithm and hmac algorithm</returns> public static void GetHashAlgorithm(dwHashAlgoV2_Values hashAlgo, out HashAlgorithm hashAlgorithm, out HMAC hmacAlgorithm) { switch (hashAlgo) { case dwHashAlgoV2_Values.TRUNCATED_SHA512: hashAlgorithm = HashAlgorithm.Create("SHA512"); hmacAlgorithm = HMAC.Create("HMACSHA512"); break; default: throw new NotImplementedException(); } }
public Pbkdf2(HMAC algorithm, Byte[] password, Byte[] salt, Int32 iterations) { if (algorithm == null) { throw new ArgumentNullException("algorithm", "HMAC algorithm cannot be null."); } if (salt == null) { throw new ArgumentNullException("salt", "Salt cannot be null."); } if (password == null) { throw new ArgumentNullException("password", "Password cannot be null."); } this.hmacAlg = algorithm; this.hmacAlg.Key = password; this.salt = salt; this.itercount = iterations; this.blocksize = this.hmacAlg.HashSize / 8; this.baBuffer = new byte[this.blocksize]; }
/// <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); }
/// <summary> /// Creates new instance. /// </summary> /// <param name="algorithm">HMAC algorithm to use.</param> /// <param name="password">The password used to derive the key.</param> /// <param name="salt">The key salt used to derive the key.</param> /// <param name="iterations">The number of iterations for the operation.</param> /// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception> public Pbkdf2(HMAC algorithm, byte[] password, byte[] salt, int iterations) { if (algorithm == null) throw new ArgumentNullException(nameof(algorithm), "Algorithm cannot be null."); if (password == null) throw new ArgumentNullException(nameof(password), "Password cannot be null."); if (salt == null) throw new ArgumentNullException(nameof(salt), "Salt cannot be null."); this.Algorithm = algorithm; this.Algorithm.Key = password; this.Salt = salt; this.IterationCount = iterations; _blockSize = this.Algorithm.HashSize / 8; }
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; }
public HMAC(string algorithmName) { if (!algorithmName.Equals("HMACSHA256", StringComparison.CurrentCultureIgnoreCase)) { throw new ArgumentException(string.Format("Unsupported algorihtm \"{0}\".", algorithmName), "algorithmName"); } #if WINDOWS_STORE this.algorithmName = MacAlgorithmNames.HmacSha256; this.hashSize = 256; #else this.hmac = System.Security.Cryptography.HMAC.Create(algorithmName); #endif }
/// <summary> /// ctor /// </summary> /// <param name="password">password</param> /// <param name="saltSize">saltSize</param> /// <param name="iterations">iterations</param> public PBKDF2(Func<HMAC> hmacFactory, string password, int saltSize, int iterations) { if (saltSize < 0) { throw new ArgumentOutOfRangeException("saltSize"); } byte[] data = new byte[saltSize]; rng.NextBytes(data); this.Salt = data; this.IterationCount = iterations; this.hmac = hmacFactory(); this.hmac.Key = password.SerializeToBytes(); this.BlockSize = hmac.HashSize / 8; this.Initialize(); }
public Pbkdf2Advanced(IEnumerable password, byte[] salt, uint iterations /*=1000*/, Type mode /* = typeof(HMACSHA256)*/) { _salt = salt; _iterations = iterations; if (mode.IsSubclassOf(typeof(System.Security.Cryptography.HMAC))) { _hmac = (System.Security.Cryptography.HMAC)Activator.CreateInstance(mode, password); } else { throw new ArgumentException("You did not supply a valid Hashing algorithm"); } Reset(); }
/// <summary> /// HMAC Hash /// </summary> /// <param name="algorithmName">HMACMD5, HMACSHA1, HMACSHA256, HMACSHA512 ...</param> /// <param name="key"></param> /// <param name="text"></param> /// <returns></returns> public static byte[] HMAC(string algorithmName, string key, string text) { ThrowHelper.ThrowIfNull(algorithmName, "algorithmName"); ThrowHelper.ThrowIfNull(key, "key"); ThrowHelper.ThrowIfNull(text, "text"); var bKey = UTF8Encoding.GetBytes(key); var buffer = UTF8Encoding.GetBytes(text); using (var hashAlgorithm = HMACCrypt.Create(algorithmName)) { hashAlgorithm.Key = bKey; return(hashAlgorithm.ComputeHash(buffer)); } }
/// <summary> /// Generates PIN code based on given Base32 secret code, interval length, and desired PIN code length /// </summary> /// <param name="secret">Base32 Secret Code</param> /// <returns>PIN code with desired number of digits</returns> public string computePin(string secret) { string strToReturn = ""; try { byte[] keyBytes = FromBase32String(secret); mac = new HMACSHA1(keyBytes); mac.Initialize(); strToReturn = generateResponseCode(getCurrentInterval()); } catch (Exception e) { return e.Message; } return strToReturn; }
static readonly byte[] emptyArray64 = new byte[64]; // for SHA-512 public HKDF(Func<HMAC> hmacFactory, byte[] ikm, byte[] salt = null, byte[] context = null) { hmac = hmacFactory(); hmac2 = hmac as HMAC2; hashLength = hmac.HashSize >> 3; // a malicious implementation of HMAC could conceivably mess up the shared static empty byte arrays, which are still writeable... hmac.Key = salt ?? (hashLength == 48 ? emptyArray48 : hashLength == 64 ? emptyArray64 : hashLength == 32 ? emptyArray32 : hashLength == 20 ? emptyArray20 : new byte[hashLength]); // re-keying hmac with PRK hmac.TransformBlock(ikm, 0, ikm.Length, null, 0); hmac.TransformFinalBlock(ikm, 0, 0); hmac.Key = (hmac2 != null) ? hmac2.HashInner : hmac.Hash; hmac.Initialize(); this.context = context; Reset(); }
/// <summary> /// Generates a new HOTP code using the supplied HMAC generater, key, counter and /// HOTP length. /// </summary> /// <param name="hmac">The HMAC algorithm to use</param> /// <param name="secretKey">The secret key used in HMAC-ing the counter</param> /// <param name="counter">The counter to use to generate a HOTP code for</param> /// <param name="hotpLength">The required length of the generated HOTP code</param> /// <returns>The generated HOTP code</returns> /// <exception cref="System.ArgumentNullException">Thrown if hmac or secretKey is null</exception> /// <exception cref="System.ArgumentException">Thrown if secretKey is empty or hotpLength is not a valid value</exception> public static string Generate(byte[] secretKey, ulong counter, HMAC hmac, OneTimePasswordLength hotpLength) { #region Input validation Insist.IsNotNull(hmac, "hmac"); Insist.IsNotNull(secretKey, "secretKey"); Insist.IsNotEmpty(secretKey, "secretKey"); Insist.IsDefined<OneTimePasswordLength>(hotpLength, "hotpLength"); #endregion byte[] hashedCounter = HashCounter(hmac, secretKey, counter); uint truncatedHash = DynamicTruncate(hashedCounter); //Convert to string and preserve leading 0s return GenerateHotpValue(truncatedHash, hotpLength).ToString("D" + (int)hotpLength); }
// 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; } }
}// 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()
/// <summary> /// Get the hash algorithm and hmac algorithm for V1. /// </summary> /// <param name="hashAlgo">The hash algorithm value</param> /// <returns>The hash algorithm and hmac algorithm</returns> public static void GetHashAlgorithm(dwHashAlgo_Values hashAlgo, out HashAlgorithm hashAlgorithm, out HMAC hmacAlgorithm, out int blockHashSize) { switch (hashAlgo) { case dwHashAlgo_Values.SHA256: hashAlgorithm = HashAlgorithm.Create("SHA256"); hmacAlgorithm = HMAC.Create("HMACSHA256"); blockHashSize = 32; break; case dwHashAlgo_Values.SHA384: hashAlgorithm = HashAlgorithm.Create("SHA384"); hmacAlgorithm = HMAC.Create("HMACSHA384"); blockHashSize = 48; break; case dwHashAlgo_Values.SHA512: hashAlgorithm = HashAlgorithm.Create("SHA512"); hmacAlgorithm = HMAC.Create("HMACSHA512"); blockHashSize = 64; break; default: throw new NotImplementedException(); } }
/// <summary> /// Implements RFC2898 Password Based Key Derivation Function #2 /// </summary> /// <param name="password">password to be used as hash key</param> /// <param name="salt">salt</param> /// <param name="iterationCount">number of iterations to perform</param> /// <param name="keyBitLength">desired key length in bits to detive</param> /// <param name="prf">Pseudo Random Function, HMAC will be inited with key equal to given password</param> /// <returns></returns> public static byte[] DeriveKey(byte[] password, byte[] salt, int iterationCount, int keyBitLength, HMAC prf) { prf.Key = password; // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. Ensure.MaxValue(keyBitLength, 4294967295, "PBKDF2 expect derived key size to be not more that (2^32-1) bits, but was requested {0} bits.",keyBitLength); int hLen=prf.HashSize / 8; //size of mac in bytes int dkLen = keyBitLength /8; //size of derived key in bytes int l = (int)Math.Ceiling(dkLen / (double)hLen); // l = CEIL (dkLen / hLen) , int r = dkLen - (l - 1) * hLen; // r = dkLen - (l - 1) * hLen . byte[][] T = new byte[l][]; for (int i = 0; i < l; i++) { T[i] = F(salt, iterationCount, i + 1, prf); // T_l = F (P, S, c, l) } T[l - 1] = Arrays.LeftmostBits(T[l - 1], r * 8); //truncate last block to r bits return Arrays.Concat(T); // DK = T_1 || T_2 || ... || T_l<0..r-1> }
public void SP800_108_SHA512() { /* [PRF=HMAC_SHA512] [CTRLOCATION=BEFORE_FIXED] [RLEN=32_BITS] */ hmac = HMACFactories.HMACSHA512(); // COUNT=0 hmac.Key = "dd5dbd45593ee2ac139748e7645b450f223d2ff297b73fd71cbcebe71d41653c950b88500de5322d99ef18dfdd30428294c4b3094f4c954334e593bd982ec614".FromBase16(); buffer = new ArraySegment<byte>("00000001b50b0c963c6b3034b8cf19cd3f5c4ebe4f4985af0c03e575db62e6fdf1ecfe4f28b95d7ce16df85843246e1557ce95bb26cc9a21974bbd2eb69e8355".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[128 / 8]); expected = "e5993bf9bd2aa1c45746042e12598155"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=10 hmac.Key = "5be2bf7f5e2527e15fe65cde4507d98ba55457006867de9e4f36645bcff4ca38754f92898b1c5544718102593b8c26d45d1fceaea27d97ede9de8b9ebfe88093".FromBase16(); buffer = new ArraySegment<byte>("00000001004b13c1f628cb7a00d9498937bf437b71fe196cc916c47d298fa296c6b86188073543bbc66b7535eb17b5cf43c37944b6ca1225298a9e563413e5bb".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[256 / 8]); expected = "cee0c11be2d8110b808f738523e718447d785878bbb783fb081a055160590072"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=20 hmac.Key = "9dd03864a31aa4156ca7a12000f541680ce0a5f4775eef1088ac13368200b447a78d0bf14416a1d583c54b0f11200ff4a8983dd775ce9c0302d262483e300ae6".FromBase16(); buffer = new ArraySegment<byte>("00000001037369f142d669fca9e87e9f37ae8f2c8d506b753fdfe8a3b72f75cac1c50fa1f8620883b8dcb8dcc67adcc95e70aa624adb9fe1b2cb396692b0d2e8".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[160 / 8]); expected = "96e8d1bc01dc95c0bf42c3c38fc54c090373ced4"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=30 hmac.Key = "a9f4a2c5af839867f5db5a1e520ab3cca72a166ca60de512fd7fe7e64cf94f92cf1d8b636175f293e003275e021018c3f0ede495997a505ec9a2afeb0495be57".FromBase16(); buffer = new ArraySegment<byte>("000000018e9db3335779db688bcfe096668d9c3bc64e193e3529c430e68d09d56c837dd6c0f94678f121a68ee1feea4735da85a49d34a5290aa39f7b40de435f".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[320 / 8]); expected = "6db880daac98b078ee389a2164252ded61322d661e2b49247ea921e544675d8f17af2bf66dd40d81"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); }// SP800_108_SHA512
public void SP800_108_SHA384() { /* [PRF=HMAC_SHA384] [CTRLOCATION=BEFORE_FIXED] [RLEN=32_BITS] */ hmac = HMACFactories.HMACSHA384(); // COUNT=0 hmac.Key = "216ed044769c4c3908188ece61601af8819c30f501d12995df608e06f5e0e607ab54f542ee2da41906dfdb4971f20f9d".FromBase16(); buffer = new ArraySegment<byte>("00000001638e9506a2c7be69ea346b84629a010c0e225b7548f508162c89f29c1ddbfd70472c2b58e7dc8aa6a5b06602f1c8ed4948cda79c62708218e26ac0e2".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[128 / 8]); expected = "d4b144bb40c7cabed13963d7d4318e72"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=10 hmac.Key = "8fca201473433f2dc8f6ae51e48de1a5654ce687e711d2d65f0dc5da6fee9a6a3db9d8535d3e4455ab53d35850c88272".FromBase16(); buffer = new ArraySegment<byte>("00000001195bd88aa2d4211912334fe2fd9bd24522f7d9fb08e04747609bc34f2538089a9d28bbc70b2e1336c3643753cec6e5cd3f246caa915e3c3a6b94d3b6".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[256 / 8]); expected = "f51ac86b0f462388d189ed0197ef99c2ff3a65816d8442e5ea304397b98dd11f"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=20 hmac.Key = "bc3157b8932e88d1b1cf8e4622137010a242d3527b1d23d6d9c0db9cc9edfc20e5135de823977bf4defafae44d6cdab6".FromBase16(); buffer = new ArraySegment<byte>("00000001b42a8e43cc2d4e5c69ee5e4f6b19ff6b8071d26bab4dfe45650b92b1f47652d25162d4b61441d8448c54918ae568ae2fb53091c624dbfffacee51d88".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[160 / 8]); expected = "91314bdf542162031643247d6507838eaba50f1a"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); // COUNT=30 hmac.Key = "582f968a54b8797b9ea8c655b42e397adb73d773b1984b1e1c429cd597b8015d2f91d59e4136a9d523bf6491a4733c7a".FromBase16(); buffer = new ArraySegment<byte>("00000001e6d3c193eff34e34f8b7b00e66565aeb01f63206bb27e27aa281592afc06ae1ec5b7eb97a39684ce773d7c3528f2667c1f5d428406e78ce4cf39f652".FromBase16()); outBuffer = new ArraySegment<byte>(new byte[320 / 8]); expected = "691726c111e5030b5f9657069107861ecc18bc5835a814c3d2e5092c901cb1fb6c1a7cd3eb0be2a7"; SP800_108_Ctr.DeriveKey(hmac, buffer, outBuffer); calculated = outBuffer.ToBase16(Base16Config.HexLowercase); Assert.IsTrue(calculated == expected); }// SP800_108_SHA384
/// <summary>Creates an instance of the default implementation of a Hash-based Message Authentication Code (HMAC).</summary> /// <returns>A new SHA-1 instance, unless the default settings have been changed by using the <cryptoClass> element.</returns> // Token: 0x060021B3 RID: 8627 RVA: 0x000774EA File Offset: 0x000756EA public new static HMAC Create() { return(HMAC.Create("System.Security.Cryptography.HMAC")); }