public static byte[] GetStringHash(string val, byte[] salt, int length)
        {
            byte[]     secretKey = SecretKeyStorage.Instance.SecretKey;
            HMACSHA512 hmac512   = new HMACSHA512(secretKey);

            //
            // Add the data
            //

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write(val);
            bw.Close();

            hmac512.TransformBlock(salt, 0, salt.Length, salt, 0);
            hmac512.TransformFinalBlock(ms.ToArray(), 0, ms.ToArray().Length);

            //
            // Return the hash
            //

            Pbkdf2 pbkdf2 = new Pbkdf2(hmac512, hmac512.Hash, secretKey);

            return(pbkdf2.GetBytes(length));
        }
        private static void TestEncryptWithHmacHelper(int length, AxCryptOptions options)
        {
            byte[] output;
            byte[] hmacKey;
            using (MemoryStream inputStream = new MemoryStream())
            {
                byte[] text = Resolve.RandomGenerator.Generate(length);
                inputStream.Write(text, 0, text.Length);
                inputStream.Position = 0;
                using (MemoryStream outputStream = new MemoryStream())
                {
                    using (V2AxCryptDocument document = new V2AxCryptDocument(new EncryptionParameters(new V2Aes256CryptoFactory().CryptoId, new Passphrase("Secret")), 100))
                    {
                        document.EncryptTo(inputStream, outputStream, options);
                        output  = outputStream.ToArray();
                        hmacKey = document.DocumentHeaders.GetHmacKey();
                    }
                }
            }

            byte[] hmacBytesFromHeaders = new byte[V2Hmac.RequiredLength];
            Array.Copy(output, output.Length - V2Hmac.RequiredLength, hmacBytesFromHeaders, 0, V2Hmac.RequiredLength);
            V2Hmac hmacFromHeaders = new V2Hmac(hmacBytesFromHeaders);

            byte[] dataToHmac = new byte[output.Length - (V2Hmac.RequiredLength + 5)];
            Array.Copy(output, 0, dataToHmac, 0, dataToHmac.Length);

            HMACSHA512 hmac = new HMACSHA512(hmacKey);

            hmac.TransformFinalBlock(dataToHmac, 0, dataToHmac.Length);
            V2Hmac hmacFromCalculation = new V2Hmac(hmac.Hash);

            Assert.That(hmacFromHeaders, Is.EqualTo(hmacFromCalculation));
        }
        public static byte[] GetStringColumnValueThumbprint(
            byte[] secretKey,
            string colVal,
            string extraData)
        {
            HMACSHA512 hmac512 = new HMACSHA512(secretKey);

            //
            // Add the data
            //

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write(colVal);
            bw.Write(extraData);
            bw.Close();

            hmac512.TransformFinalBlock(
                ms.ToArray(),
                0,
                ms.ToArray().Length);

            //
            // Return the hash
            //

            return(hmac512.Hash);
        }
        public static byte[] GetStringColumnValueThumbprint(
            byte[] secretKey,
            string colVal,
            string extraData)
        {
            HMACSHA512 hmac512 = new HMACSHA512(secretKey);

            //
            // Add the data
            //

            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write(colVal);
            bw.Write(extraData);
            bw.Close();

            hmac512.TransformFinalBlock(
                ms.ToArray(),
                0,
                ms.ToArray().Length);

            //
            // Return the hash
            //

            Pbkdf2 pbkdf2 = new Pbkdf2(hmac512, hmac512.Hash, secretKey, NumberOfRoundsForSecurEntity);

            return(pbkdf2.GetBytes(HashBlockLength));
        }
        public void TestWriteWithHmac()
        {
            V2DocumentHeaders headers = new V2DocumentHeaders(new EncryptionParameters(new V2Aes256CryptoFactory().CryptoId, new Passphrase("v2passzz")), 20);

            byte[]           output;
            V2HmacCalculator hmacCalculator = new V2HmacCalculator(new SymmetricKey(headers.GetHmacKey()));

            using (V2HmacStream <MemoryStream> hmacStream = V2HmacStream.Create <MemoryStream>(hmacCalculator, new MemoryStream()))
            {
                headers.WriteStartWithHmac(hmacStream);
                headers.WriteEndWithHmac(hmacCalculator, hmacStream, 0, 0);
                hmacStream.Flush();
                output = hmacStream.Chained.ToArray();
            }

            byte[] hmacBytesFromHeaders = new byte[V2Hmac.RequiredLength];
            Array.Copy(output, output.Length - V2Hmac.RequiredLength, hmacBytesFromHeaders, 0, V2Hmac.RequiredLength);
            V2Hmac hmacFromHeaders = new V2Hmac(hmacBytesFromHeaders);

            byte[] dataToHmac = new byte[output.Length - (V2Hmac.RequiredLength + 5)];
            Array.Copy(output, 0, dataToHmac, 0, dataToHmac.Length);

            HMACSHA512 hmac = new HMACSHA512(headers.GetHmacKey());

            hmac.TransformFinalBlock(dataToHmac, 0, dataToHmac.Length);
            V2Hmac hmacFromCalculation = new V2Hmac(hmac.Hash);

            Assert.That(hmacFromHeaders, Is.EqualTo(hmacFromCalculation));
        }
 /// <summary>
 ///     Calculates an HMAC authentication code over the given encrypted value
 /// </summary>
 /// <param name="value">The value to authenticate</param>
 /// <returns>The HMAC authentication code</returns>
 public byte[] Hmac([NotNull] byte[] value)
 {
     using (var hmac = new HMACSHA512(HmacKey))
     {
         hmac.TransformBlock(value, 0, value.Length, null, 0);
         hmac.TransformFinalBlock(_salt, 0, _salt.Length);
         return(hmac.Hash);
     }
 }
        public void AddData(
            byte[] data,
            AddDataAction action,
            bool final,
            ref string plaintext,
            ref string ciphertext)
        {
            //
            // Need to decrypt?
            //

            if (AddDataAction.Decrypt == action)
            {
                byte[]           decoded   = Convert.FromBase64String(ciphertext);
                ICryptoTransform decryptor = _aes.CreateDecryptor();
                byte[]           decrypted = decryptor.TransformFinalBlock(
                    decoded, 0, decoded.Length);

                data = decrypted;

                using (MemoryStream ms = new MemoryStream(decrypted))
                {
                    BinaryReader bw = new BinaryReader(ms);
                    plaintext = bw.ReadString();
                }
            }

            //
            // Add the property to integrity
            //

            if (false == final)
            {
                _hmac512.TransformBlock(
                    data, 0, data.Length, data, 0);
            }
            else
            {
                _hmac512.TransformFinalBlock(data, 0, data.Length);
            }

            //
            // Need to encrypt?
            //

            if (AddDataAction.Encrypt == action)
            {
                ICryptoTransform encryptor = _aes.CreateEncryptor();
                byte[]           toEncode  = encryptor.TransformFinalBlock(
                    data, 0, data.Length);
                ciphertext = Convert.ToBase64String(toEncode);
            }
        }
Exemple #8
0
        public static byte[] ComputeHMACSHA512HashFromFile(string filePath, byte[] authKey, long startPosition, long endPosition)
        {
            byte[] hash = null;

            using (var fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                fStream.Position = startPosition;
                byte[] buffer = new byte[(1024 * 4)];
                long   amount = (endPosition - startPosition);

                using (var hmacSha512 = new HMACSHA512(authKey))
                {
                    while (amount > 0)
                    {
                        int bytesRead = fStream.Read(buffer, 0, (int)Math.Min(buffer.Length, amount));

                        if (bytesRead > 0)
                        {
                            amount -= bytesRead;

                            if (amount > 0)
                            {
                                hmacSha512.TransformBlock(buffer, 0, bytesRead, buffer, 0);
                            }
                            else
                            {
                                hmacSha512.TransformFinalBlock(buffer, 0, bytesRead);
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }

                    hash = hmacSha512.Hash;
                }
            }

            return(hash);
        }
        public static bool TryDecrypt(byte[] Source, byte[] Passphrase, out byte[] Result)
        {
            if (Source == null || Source.Length == 0)
            {
                throw new ArgumentOutOfRangeException("Cannot decrypt an empty payload!");
            }
            if (Source.Length < CIPHERTEXT_START)
            {
                Result = null;
                return(false); // not a complete header, nothing to decrypt
            }
            //test: is this the correct version and is this a TripleSec payload to begin with?
            byte[] buffer = new byte[4 + 4];
            Buffer.BlockCopy(Source, 0, buffer, 0, buffer.Length);
            if (buffer.ToHexString() != TRIPLESEC_MAGICPLUSVERSION4_HEXBYTES)
            {
                throw new ArgumentException("Not a TripleSec v3 encrypted payload!");
            }

            byte[] theSalt = new byte[SALT_LEN];
            Buffer.BlockCopy(Source, SALT_START, theSalt, 0, SALT_LEN);
            // need the keys to verify the signatures
#if DEBUG
#pragma warning disable 618 // we know in DEBUG mode this will throw an Obsolete warning; this is a legitimate use of this function, so supress it
#endif
            KeysV4 keys = new KeysV4(Passphrase, theSalt);
#if DEBUG
#pragma warning restore 618
#endif
            // VERIFY SIGNATURES HERE
            // get existing signatures
            byte[] SENT_HMACSHA512 = new byte[HMACSHA512_LEN];
            Buffer.BlockCopy(Source, HMACSHA512_START, SENT_HMACSHA512, 0, HMACSHA512_LEN);
            byte[] SENT_HMACSHA3_512 = new byte[HMACSHA3_512_LEN];
            Buffer.BlockCopy(Source, HMACSHA3_512_START, SENT_HMACSHA3_512, 0, HMACSHA3_512_LEN);
            string SENT_SIGNATURE = Utilities.BytesToHexString(SENT_HMACSHA512) + Utilities.BytesToHexString(SENT_HMACSHA3_512);

            //calculate hash on sent data before decryption
            int sourceLength = Source.Length - CIPHERTEXT_START; // the AES_IV isn't counted here

            byte[] AES_IV = new byte[AES_IV_LEN];                // we need the AES_IV as part of the hmac calculations
            Buffer.BlockCopy(Source, AES_IV_START, AES_IV, 0, AES_IV_LEN);

            HMACSHA512 sha512 = new HMACSHA512(keys.HMACSHA512_KEY);
            SHA3Managed.HMACSHA3_512 sha3_512 = new SHA3Managed.HMACSHA3_512(keys.HMACSHA3_512_KEY);
            sha512.TransformBlock(TRIPLESEC_MAGICPLUSVERSION4_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION4_BYTELENGTH, TRIPLESEC_MAGICPLUSVERSION4_BYTES, 0);
            sha3_512.HashCore(TRIPLESEC_MAGICPLUSVERSION4_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION4_BYTELENGTH);
            sha512.TransformBlock(theSalt, 0, theSalt.Length, theSalt, 0);
            sha3_512.HashCore(theSalt, 0, theSalt.Length);
            sha512.TransformBlock(AES_IV, 0, AES_IV.Length, AES_IV, 0);
            sha3_512.HashCore(AES_IV, 0, AES_IV.Length);
            sha512.TransformBlock(Source, CIPHERTEXT_START, sourceLength, Source, CIPHERTEXT_START);
            sha3_512.HashCore(Source, CIPHERTEXT_START, sourceLength);
            sha512.TransformFinalBlock(Source, 0, 0);
            sha3_512.HashFinal(Source, 0, 0);
//#if DEBUG
//            System.Diagnostics.Debug.Print("DECRYPT SIGNATURES:");
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha512.Hash).Replace("-", ""));
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha3_512.Hash).Replace("-", ""));
//#endif
            string CALCULATED_SIGNATURE = Utilities.BytesToHexString(sha512.Hash) + Utilities.BytesToHexString(sha3_512.Hash);

            if (CALCULATED_SIGNATURE != SENT_SIGNATURE)
            {
                Result = null;
                return(false);
            }
            //==================================================================================

            byte[] OUTPUT = new byte[sourceLength];
            // AES is first (outermost)
            BC.Crypto.Modes.SicBlockCipher mySIC_AES = new BC.Crypto.Modes.SicBlockCipher(new BC.Crypto.Engines.AesEngine());
            mySIC_AES.Init(true,
                           new BC.Crypto.Parameters.ParametersWithIV(
                               new BC.Crypto.Parameters.KeyParameter(keys.AES_KEY),
                               AES_IV));
            ProcessArray(mySIC_AES, Source, CIPHERTEXT_START, OUTPUT, 0, sourceLength);

            //Twofish is REMOVED IN V4

            // prepare for next
            byte[] IV_XSALSA20 = new byte[24];
            Buffer.BlockCopy(OUTPUT, 0, IV_XSALSA20, 0, IV_XSALSA20.Length);
            byte[] INPUT = new byte[OUTPUT.Length - IV_XSALSA20.Length];
            Buffer.BlockCopy(OUTPUT, IV_XSALSA20.Length, INPUT, 0, INPUT.Length);
            OUTPUT.Wipe(); // DON'T LEAK!

            //XSalsa20 is last
            OUTPUT = Chaos.NaCl.XSalsa20.Process(INPUT, keys.XSalsa20_KEY, IV_XSALSA20);
            INPUT.Wipe(); // DON'T LEAK!
            Result = OUTPUT;
            return(true);
        }
        /// <summary>
        /// Encrypt an array of bytes using the TripleSec protocol with the supplied passphrase.  Internal function, not intended for use by an end coder.
        /// </summary>
        /// <param name="Source">Source array of bytes to process.</param>
        /// <param name="Keys">The KeysV3 object initialized with the proper keys.</param>
        /// <param name="IVs">The RNGV3 object initialized with the proper initialization arrays.</param>
        /// <returns>The encrypted array.</returns>
        internal static byte[] Encrypt(byte[] Source, KeysV4 Keys, RNGV4 IVs)
#endif
        {
            if (Source == null || Source.Length == 0)
            {
                throw new ArgumentNullException("Source");
            }
            if (Keys == null || !Keys.IsInitialized || IVs == null || !IVs.IsInitialized)
            {
                throw new InvalidOperationException("Keys and IVs objects must not be null (and both must be initialized)");
            }

            // the added IV's and the signatures and the header always add up to the same length added to the original message length
            //  if we're going to run out of memory, it will be here, or shortly thereafter
            byte[] OUT_BUFFER = new byte[Source.Length + 192];
            //standard header stuff
            // All the header pieces are now copied by the built-in SHA512 method TransformBlock

            //XSalsa20 is up first
            byte[] interim  = Chaos.NaCl.XSalsa20.Process(Source, Keys.XSalsa20_KEY, IVs.XSalsa20_IV);
            byte[] interim2 = new byte[interim.Length + IVs.XSalsa20_IV.Length]; // IV included here as it is part of the input to the next process
            Buffer.BlockCopy(IVs.XSalsa20_IV, 0, interim2, 0, IVs.XSalsa20_IV.Length);
            Buffer.BlockCopy(interim, 0, interim2, IVs.XSalsa20_IV.Length, interim.Length);

            ////Twofish is REMOVED FROM V4

            //AES is last
            interim.Wipe(); // DON'T LEAK!
            BC.Crypto.Modes.SicBlockCipher aes = new BC.Crypto.Modes.SicBlockCipher(new BC.Crypto.Engines.AesEngine());
            aes.Init(true, new BC.Crypto.Parameters.ParametersWithIV(new BC.Crypto.Parameters.KeyParameter(Keys.AES_KEY), IVs.AES_IV));
            ProcessArray(aes, interim2, interim2); // process array in-place
            // buffer is copied to output by built-in HMACSHA512 TransFormBlock
            aes.Reset();
            aes = null;

            HMACSHA512 sha512 = new HMACSHA512(Keys.HMACSHA512_KEY);

            sha512.TransformBlock(TRIPLESEC_MAGICPLUSVERSION4_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION4_BYTELENGTH, OUT_BUFFER, 0);
            sha512.TransformBlock(Keys.Salt, 0, Keys.Salt.Length, OUT_BUFFER, SALT_START);
            sha512.TransformBlock(IVs.AES_IV, 0, IVs.AES_IV.Length, OUT_BUFFER, AES_IV_START);
            sha512.TransformBlock(interim2, 0, interim2.Length, OUT_BUFFER, CIPHERTEXT_START);
            sha512.TransformFinalBlock(interim2, 0, 0); // transform final block doesn't copy the output
            Buffer.BlockCopy(sha512.Hash, 0, OUT_BUFFER, HMACSHA512_START, sha512.Hash.Length);

            SHA3Managed.HMACSHA3_512 sha3_512 = new SHA3Managed.HMACSHA3_512(Keys.HMACSHA3_512_KEY);
            sha3_512.HashCore(TRIPLESEC_MAGICPLUSVERSION4_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION4_BYTELENGTH);
            sha3_512.HashCore(Keys.Salt, 0, Keys.Salt.Length);
            sha3_512.HashCore(IVs.AES_IV, 0, IVs.AES_IV.Length);
            sha3_512.HashCore(interim2, 0, interim2.Length);
            sha3_512.HashFinal(interim2, 0, 0); // transform final block doesn't copy the output
            Buffer.BlockCopy(sha3_512.Hash, 0, OUT_BUFFER, HMACSHA3_512_START, sha3_512.Hash.Length);
//#if DEBUG
//            System.Diagnostics.Debug.Print("ENCRYPT SIGNATURES: HMACSHA512, HMACSHA3_512, CipherText");
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha512.Hash).Replace("-", "").ToLowerInvariant());
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha3_512.Hash).Replace("-", "").ToLowerInvariant());
//            System.Diagnostics.Debug.Print(BitConverter.ToString(OUT_BUFFER).Replace("-","").ToLowerInvariant());
//#endif
            // HASHLIB REMOVED -------- !

            return(OUT_BUFFER);
        }
        /// <summary>
        /// Encrypt an array of bytes using the TripleSec protocol with the supplied passphrase.  Internal function, not intended for use by an end coder.
        /// </summary>
        /// <param name="Source">Source array of bytes to process.</param>
        /// <param name="Keys">The KeysV3 object initialized with the proper keys.</param>
        /// <param name="IVs">The RNGV3 object initialized with the proper initialization arrays.</param>
        /// <returns>The encrypted array.</returns>
        internal static byte[] Encrypt(byte[] Source, KeysV3 Keys, RNGV3 IVs)
#endif
        {
            if (Source == null || Source.Length == 0)
            {
                throw new ArgumentNullException("Source");
            }
            if (Keys == null || !Keys.IsInitialized || IVs == null || !IVs.IsInitialized)
            {
                throw new InvalidOperationException("Keys and IVs objects must not be null (and both must be initialized)");
            }

            // the added IV's and the signatures and the header always add up to the same length added to the original message length
            //  if we're going to run out of memory, it will be here, or shortly thereafter
            byte[] OUT_BUFFER = new byte[Source.Length + 208];
            //standard header stuff
            // All the header pieces are now copied by the built-in SHA512 method TransformBlock

            //XSalsa20 is up first
            byte[] interim  = Chaos.NaCl.XSalsa20.Process(Source, Keys.XSalsa20_KEY, IVs.XSalsa20_IV);
            byte[] interim2 = new byte[interim.Length + IVs.XSalsa20_IV.Length]; // IV included here as it is part of the input to the next process
            Buffer.BlockCopy(IVs.XSalsa20_IV, 0, interim2, 0, IVs.XSalsa20_IV.Length);
            Buffer.BlockCopy(interim, 0, interim2, IVs.XSalsa20_IV.Length, interim.Length);

            //Twofish is up next
            interim.Wipe();                                              // DON'T LEAK!
            interim = new byte[interim2.Length + IVs.Twofish_IV.Length]; // IV included here as it is part of the input to the next process
            Buffer.BlockCopy(IVs.Twofish_IV, 0, interim, 0, IVs.Twofish_IV.Length);
            BC.Crypto.Modes.SicBlockCipher tf = new BC.Crypto.Modes.SicBlockCipher(new BC.Crypto.Engines.TwofishEngine());
            tf.Init(true, new BC.Crypto.Parameters.ParametersWithIV(new BC.Crypto.Parameters.KeyParameter(Keys.Twofish_KEY), IVs.Twofish_IV));
            ProcessArray(tf, interim2, interim2); // process array in-place
            Buffer.BlockCopy(interim2, 0, interim, IVs.Twofish_IV.Length, interim2.Length);
            tf.Reset(); tf = null;

            //AES is last
            interim2.Wipe(); // DON'T LEAK!
            BC.Crypto.Modes.SicBlockCipher aes = new BC.Crypto.Modes.SicBlockCipher(new BC.Crypto.Engines.AesEngine());
            aes.Init(true, new BC.Crypto.Parameters.ParametersWithIV(new BC.Crypto.Parameters.KeyParameter(Keys.AES_KEY), IVs.AES_IV));
            ProcessArray(aes, interim, interim); // process array in-place
            //the HMACSHA512 process will copy the data to the output as it hashes
            aes.Reset();
            aes = null;

            HMACSHA512 sha512 = new HMACSHA512(Keys.HMACSHA512_KEY);

            sha512.TransformBlock(TRIPLESEC_MAGICPLUSVERSION3_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION3_BYTELENGTH, OUT_BUFFER, 0);
            sha512.TransformBlock(Keys.Salt, 0, Keys.Salt.Length, OUT_BUFFER, SALT_START);
            sha512.TransformBlock(IVs.AES_IV, 0, IVs.AES_IV.Length, OUT_BUFFER, AES_IV_START);
            sha512.TransformBlock(interim, 0, interim.Length, OUT_BUFFER, CIPHERTEXT_START);
            sha512.TransformFinalBlock(interim, 0, 0); // transform final block doesn't copy the output
            Buffer.BlockCopy(sha512.Hash, 0, OUT_BUFFER, HMACSHA512_START, sha512.Hash.Length);


            // Proposed SHA3 uses a delimiter/padding byte of 0x01 intead of 0x06 or 0x1f (SHAKE128/256), that's the only difference
            // This is IMPORTANT for V3, as it used a pre-release version of the proposed SHA3 standard.  NIST changed SHA3 well after
            //  TripleSec was released and had been used in the wild.
            SHA3Managed.HMAC_Proposed_SHA3_512 sha3_512 = new SHA3Managed.HMAC_Proposed_SHA3_512(Keys.HMACKeccak512_KEY);
            sha3_512.HashCore(TRIPLESEC_MAGICPLUSVERSION3_BYTES, 0, TRIPLESEC_MAGICPLUSVERSION3_BYTELENGTH);
            sha3_512.HashCore(Keys.Salt, 0, Keys.Salt.Length);
            sha3_512.HashCore(IVs.AES_IV, 0, IVs.AES_IV.Length);
            sha3_512.HashCore(interim, 0, interim.Length);
            sha3_512.HashFinal(interim, 0, 0); // transform final block doesn't copy the output
            Buffer.BlockCopy(sha3_512.Hash, 0, OUT_BUFFER, HMACKECCAK512_START, sha3_512.Hash.Length);
//#if DEBUG
//            System.Diagnostics.Debug.Print("ENCRYPT SIGNATURES:");
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha512.Hash).Replace("-", ""));
//            System.Diagnostics.Debug.Print(BitConverter.ToString(sha3_512.Hash).Replace("-", ""));
//            System.Diagnostics.Debug.Print(BitConverter.ToString(OUT_BUFFER).Replace("-",""));
//#endif
            // HASHLIB REMOVED -----------!

            interim.Wipe(); // this isn't really leaking since it's encrypted AND copied to the output buffer, but clean house all the same.

            return(OUT_BUFFER);
        }