Inheritance: KeyedHashAlgorithm
        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));
 }
Beispiel #5
0
        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;
        }
Beispiel #6
0
        //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();
        }
Beispiel #7
0
 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();
 }
Beispiel #11
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);
 }
        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 ) );
                    }
            }
        }
Beispiel #14
0
 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();
		}
Beispiel #16
0
 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);
 }
Beispiel #17
0
 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();
 }
Beispiel #18
0
 /// <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);
        }
Beispiel #20
0
        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();
     }
 }
Beispiel #23
0
 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);
        }
Beispiel #25
0
        /// <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;
        }
Beispiel #26
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;
        }
Beispiel #27
0
        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();
 }
Beispiel #29
0
        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();
        }
Beispiel #30
0
        /// <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;
        }
Beispiel #32
0
		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();
     }
 }
Beispiel #37
0
        /// <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
Beispiel #40
0
 /// <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 &lt;cryptoClass&gt; element.</returns>
 // Token: 0x060021B3 RID: 8627 RVA: 0x000774EA File Offset: 0x000756EA
 public new static HMAC Create()
 {
     return(HMAC.Create("System.Security.Cryptography.HMAC"));
 }