예제 #1
0
 private byte[] GetDerivative(byte[] seed, byte[] key)
 {
     try {
         using(var hmac = new HMACSHA256(key))
         {
             hmac.TransformFinalBlock(seed, 0, seed.Length);
             return hmac.Hash;
         }
     }
     catch {
         throw new InvalidOperationException ("Assertion error");
     }
 }
예제 #2
0
		public void CheckE (string testName, byte[] key, byte[] data, byte[] result) 
		{
			algo = new HMACSHA256 ();
			algo.Key = key;
			byte[] copy = new byte [data.Length];
			// LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
			for (int i=0; i < data.Length - 1; i++)
				algo.TransformBlock (data, i, 1, copy, i);
			algo.TransformFinalBlock (data, data.Length - 1, 1);
			Assert.AreEqual (result, algo.Hash, testName + "e");
		}
예제 #3
0
		public void CheckD (string testName, byte[] key, byte[] data, byte[] result) 
		{
			algo = new HMACSHA256 ();
			algo.Key = key;
			// LAMESPEC or FIXME: TransformFinalBlock doesn't return HashValue !
			algo.TransformFinalBlock (data, 0, data.Length);
			Assert.AreEqual (result, algo.Hash, testName + "d");
		}
예제 #4
0
        /// <summary>
        /// Compute PBKDF2 using HMAC-SHA256 as the PRF, and write the output to derivedKey.
        /// </summary>
        private static void PBKDF2_SHA256(HMACSHA256 mac, byte[] password, byte[] salt, int saltLength, long iterationCount, byte[] derivedKey, int derivedKeyLength)
        {
            if (derivedKeyLength > (Math.Pow(2, 32) - 1) * 32)
            {
                throw new ArgumentException("Requested key length too long");
            }

            var U = new byte[32];
            var T = new byte[32];
            var saltBuffer = new byte[saltLength + 4];

            var blockCount = (int)Math.Ceiling((double)derivedKeyLength / 32);
            var r = derivedKeyLength - (blockCount - 1) * 32;

            Buffer.BlockCopy(salt, 0, saltBuffer, 0, saltLength);

            for (int i = 1; i <= blockCount; i++)
            {
                saltBuffer[saltLength + 0] = (byte)(i >> 24);
                saltBuffer[saltLength + 1] = (byte)(i >> 16);
                saltBuffer[saltLength + 2] = (byte)(i >> 8);
                saltBuffer[saltLength + 3] = (byte)(i);

                mac.Initialize();
                mac.TransformFinalBlock(saltBuffer, 0, saltBuffer.Length);
                Buffer.BlockCopy(mac.Hash, 0, U, 0, U.Length);
                Buffer.BlockCopy(U, 0, T, 0, 32);

                for (long j = 1; j < iterationCount; j++)
                {
                    mac.TransformFinalBlock(U, 0, U.Length);
                    Buffer.BlockCopy(mac.Hash, 0, U, 0, U.Length);

                    for (int k = 0; k < 32; k++)
                    {
                        T[k] ^= U[k];
                    }
                }

                Buffer.BlockCopy(T, 0, derivedKey, (i - 1) * 32, (i == blockCount ? r : 32));
            }
        }
예제 #5
0
		private void WriteSafeBlock()
		{
			byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex);

			int cbBlockSize = m_iBufferPos;
			byte[] pbBlockSize = MemUtil.Int32ToBytes(cbBlockSize);

			byte[] pbBlockHmac;
			byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex);
			using(HMACSHA256 h = new HMACSHA256(pbBlockKey))
			{
				h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length,
					pbBlockIndex, 0);
				h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length,
					pbBlockSize, 0);

				if(cbBlockSize > 0)
					h.TransformBlock(m_pbBuffer, 0, cbBlockSize, m_pbBuffer, 0);

				h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

				pbBlockHmac = h.Hash;
			}
			MemUtil.ZeroByteArray(pbBlockKey);

			MemUtil.Write(m_sBase, pbBlockHmac);
			// MemUtil.Write(m_sBase, pbBlockIndex); // Implicit
			MemUtil.Write(m_sBase, pbBlockSize);
			if(cbBlockSize > 0)
				m_sBase.Write(m_pbBuffer, 0, cbBlockSize);

			++m_uBlockIndex;
			m_iBufferPos = 0;
		}
예제 #6
0
		private bool ReadSafeBlock()
		{
			if(m_bEos) return false; // End of stream reached already

			byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32);
			if((pbStoredHmac == null) || (pbStoredHmac.Length != 32))
				throw new EndOfStreamException(KLRes.FileCorrupted + " " +
					KLRes.FileIncomplete);

			// Block index is implicit: it's used in the HMAC computation,
			// but does not need to be stored
			// byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8);
			// if((pbBlockIndex == null) || (pbBlockIndex.Length != 8))
			//	throw new EndOfStreamException();
			// ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex);
			// if((uBlockIndex != m_uBlockIndex) && m_bVerify)
			//	throw new InvalidDataException();
			byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex);

			byte[] pbBlockSize = MemUtil.Read(m_sBase, 4);
			if((pbBlockSize == null) || (pbBlockSize.Length != 4))
				throw new EndOfStreamException(KLRes.FileCorrupted + " " +
					KLRes.FileIncomplete);
			int nBlockSize = MemUtil.BytesToInt32(pbBlockSize);
			if(nBlockSize < 0)
				throw new InvalidDataException(KLRes.FileCorrupted);

			m_iBufferPos = 0;

			m_pbBuffer = MemUtil.Read(m_sBase, nBlockSize);
			if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify))
				throw new EndOfStreamException(KLRes.FileCorrupted + " " +
					KLRes.FileIncompleteExpc);

			if(m_bVerify)
			{
				byte[] pbCmpHmac;
				byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex);
				using(HMACSHA256 h = new HMACSHA256(pbBlockKey))
				{
					h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length,
						pbBlockIndex, 0);
					h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length,
						pbBlockSize, 0);

					if(m_pbBuffer.Length > 0)
						h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length,
							m_pbBuffer, 0);

					h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

					pbCmpHmac = h.Hash;
				}
				MemUtil.ZeroByteArray(pbBlockKey);

				if(!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac))
					throw new InvalidDataException(KLRes.FileCorrupted);
			}

			++m_uBlockIndex;

			if(nBlockSize == 0)
			{
				m_bEos = true;
				return false; // No further data available
			}
			return true;
		}
예제 #7
0
		private static void HmacEval(byte[] pbKey, byte[] pbMsg,
			byte[] pbExpc, string strID)
		{
			using(HMACSHA256 h = new HMACSHA256(pbKey))
			{
				h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
				h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

				byte[] pbHash = h.Hash;
				if(!MemUtil.ArraysEqual(pbHash, pbExpc))
					throw new SecurityException("HMAC-SHA-256-" + strID);

				// Reuse the object
				h.Initialize();
				h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
				h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);

				pbHash = h.Hash;
				if(!MemUtil.ArraysEqual(pbHash, pbExpc))
					throw new SecurityException("HMAC-SHA-256-" + strID + "-R");
			}
		}
예제 #8
0
        private byte[] GetMac(UInt32 messageVersion,
		                      IdentityKey senderIdentityKey,
		                      IdentityKey receiverIdentityKey,
		                      byte[] macKey, byte[] serialized)
        {
            try
            {
                byte[] fullMac;
                using(var mac = new HMACSHA256(macKey))
                {
                    if(messageVersion >= 3)
                    {
                        var SIk = senderIdentityKey.PublicKey.Serialize();
                        var RIk = receiverIdentityKey.PublicKey.Serialize();
                        mac.TransformBlock(SIk, 0, SIk.Length, null, 0);
                        mac.TransformBlock(RIk, 0, RIk.Length, null, 0);
                    }
                    fullMac = mac.TransformFinalBlock(serialized, 0, serialized.Length);
                }

                return ByteUtil.Trim(fullMac, MAC_LENGTH);
            }
            catch(Exception e)
            {
                throw new InvalidOperationException("Assertion error", e);
            }
        }
예제 #9
0
        public static byte[] Pbkdf2(byte[] password, byte[] salt, int iterations = Pbkdf2Iterations)
        {
            /*
            // Algorithm Credits to https://github.com/vexocide
            //
            // Implements PBKDF2WithHmacSHA256 in Java. Beautifully Amazing.
            using (var mac = new HMACSHA256(password))
            {
                mac.TransformBlock(salt, 0, salt.Length, salt, 0);
                byte[] i = { 0, 0, 0, 1 };
                mac.TransformFinalBlock(i, 0, i.Length);
                byte[] t = mac.Hash;
                mac.Initialize();

                byte[] u = t;
                for (uint c = 2; c <= iterations; c++)
                {
                    t = mac.ComputeHash(t);
                    for (int j = 0; j < mac.HashSize / 8; j++)
                    {
                        u[j] ^= t[j];
                    }
                }

                return u;
            }
*/
#if STANDARD
            using( var macSalt = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, password) )
#endif
            using ( var mac = new HMACSHA256(password) )
            {
#if STANDARD
                macSalt.AppendData(salt);
#else
                mac.TransformBlock(salt, 0, salt.Length, salt, 0);
#endif
                byte[] i = {0, 0, 0, 1};
#if STANDARD
                macSalt.AppendData(i);
#else
                mac.TransformFinalBlock(i, 0, i.Length);
#endif
#if STANDARD
                byte[] t = macSalt.GetHashAndReset();
#else
                byte[] t = mac.Hash;
                mac.Initialize();
#endif

                byte[] u = t;

                for( uint c = 2; c <= iterations; c++ )
                {
                    t = mac.ComputeHash(t);
                    for( int j = 0; j < mac.HashSize / 8; j++ )
                    {
                        u[j] ^= t[j];
                    }
                }

                return u;
            }
        }
예제 #10
0
        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                SaveFileDialog sfd = new SaveFileDialog();

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        byte[] AES_KEY = {
                            0xB4, 0xEB, 0x7F, 0xB9,
                            0xA9, 0xAC, 0x05, 0x92,
                            0xAB, 0x8E, 0x42, 0xAB,
                            0xCC, 0x61, 0xD0, 0xC0
                        };

                        byte[] HMAC_KEY = {
                            0x82, 0xF4, 0x1A, 0x4F,
                            0x03, 0x45, 0x65, 0x01,
                            0x2F, 0x73, 0x9C, 0x4D,
                            0x8E, 0x63, 0xA9, 0x1F,
                            0xB9, 0x2B, 0x9D, 0x4E,
                            0xE1, 0x11, 0x91, 0x47,
                            0xD4, 0x3C, 0xC6, 0x88,
                            0x3F, 0xC7, 0xFC, 0x70
                        };

                        BinaryReader reader = new BinaryReader(new FileStream(ofd.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
                        BinaryWriter writer = new BinaryWriter(new FileStream(sfd.FileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));

                        byte[] ProfileID = HexStringToByteArray(textBox1.Text);

                        if (reader.ReadUInt32() != 0x73736D63)
                            throw new Exception("Invalid File");

                        uint ReadSize = BSwapUint(reader.ReadUInt32());

                        byte[] Hash = reader.ReadBytes(0x20);
                        uint DataSizeEnc = BSwapUint(reader.ReadUInt32());
                        byte[] AES_IV = reader.ReadBytes(0x10);

                        uint DataSizeDec = DecryptDataSize(AES_IV, DataSizeEnc);
                        byte[] DataBuffer = reader.ReadBytes((int)(DataSizeDec));

                        XorAes(ref AES_KEY, ProfileID, 1);

                        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
                        aes.Mode = CipherMode.CBC;
                        aes.Padding = PaddingMode.None;

                        byte[] Encrypted = aes.CreateEncryptor(AES_KEY, AES_IV).TransformFinalBlock(DataBuffer, 0, DataBuffer.Length);

                        XorHmac(ref HMAC_KEY, ProfileID, 0);
                        HMACSHA256 hmac = new HMACSHA256(HMAC_KEY);

                        byte[] Tmp = new byte[0x14];
                        Buffer.BlockCopy(BitConverter.GetBytes(BSwapUint(DataSizeEnc)), 0, Tmp,  0, 4);
                        Buffer.BlockCopy(AES_IV, 0, Tmp, 4, 0x10);

                        hmac.TransformBlock(Tmp, 0, 0x14, null, 0);
                        hmac.TransformFinalBlock(Encrypted, 0, Encrypted.Length);

                        writer.Write(0x73736D63);
                        writer.Write(BSwapUint(ReadSize));
                        writer.Write(hmac.Hash);
                        writer.Write(BSwapUint(DataSizeEnc));
                        writer.Write(AES_IV);
                        writer.Write(Encrypted);

                        writer.Flush();
                        writer.Close();
                        reader.Close();
                    }
                    catch (Exception x)
                    {
                        MessageBox.Show(x.Message);
                    }
                }
            }
        }
        /// <summary>
        /// Prepares an authentication tag.
        /// Authentication Tag = HMAC_SHA-2-256(mac_key, versionbyte + cell_iv + cell_ciphertext + versionbyte_length)
        /// </summary>
        /// <param name="cipherText"></param>
        /// <returns></returns>
        private byte[] PrepareAuthenticationTag(byte[] iv, byte[] cipherText, int offset, int length) {
            Debug.Assert(cipherText != null);

            byte[] computedHash;
            byte[] authenticationTag = new byte[_KeySizeInBytes];

            // Raw Tag Length:
            //              1 for the version byte
            //              1 block for IV (16 bytes)
            //              cipherText.Length
            //              1 byte for version byte length

            using (HMACSHA256 hmac = new HMACSHA256(_columnEncryptionKey.MACKey)) {
                int retVal = 0;
                retVal = hmac.TransformBlock(_version, 0, _version.Length, _version, 0);
                Debug.Assert(retVal == _version.Length);
                retVal = hmac.TransformBlock(iv, 0, iv.Length, iv, 0);
                Debug.Assert(retVal == iv.Length);
                retVal = hmac.TransformBlock(cipherText, offset, length, cipherText, offset);
                Debug.Assert(retVal == length);
                hmac.TransformFinalBlock(_versionSize, 0, _versionSize.Length);
                computedHash = hmac.Hash;
            }

            Debug.Assert (computedHash.Length >= authenticationTag.Length);
            Buffer.BlockCopy (computedHash, 0, authenticationTag, 0, authenticationTag.Length);
            return authenticationTag;
        }
        /// <summary>
        /// Encryption Algorithm
        /// cell_iv = HMAC_SHA-2-256(iv_key, cell_data) truncated to 128 bits
        /// cell_ciphertext = AES-CBC-256(enc_key, cell_iv, cell_data) with PKCS7 padding.
        /// (optional) cell_tag = HMAC_SHA-2-256(mac_key, versionbyte + cell_iv + cell_ciphertext + versionbyte_length)
        /// cell_blob = versionbyte + [cell_tag] + cell_iv + cell_ciphertext
        /// </summary>
        /// <param name="plainText">Plaintext data to be encrypted</param>
        /// <param name="hasAuthenticationTag">Does the algorithm require authentication tag.</param>
        /// <returns>Returns the ciphertext corresponding to the plaintext.</returns>
        protected byte[] EncryptData(byte[] plainText, bool hasAuthenticationTag) {
            // Empty values get encrypted and decrypted properly for both Deterministic and Randomized encryptions.
            Debug.Assert(plainText != null);

            byte[] iv = new byte[_BlockSizeInBytes];

            // Prepare IV
            // Should be 1 single block (16 bytes)
            if (_isDeterministic) {
                SqlSecurityUtility.GetHMACWithSHA256(plainText, _columnEncryptionKey.IVKey, iv);
            }
            else {
                SqlSecurityUtility.GenerateRandomBytes(iv);
            }

            int numBlocks = plainText.Length / _BlockSizeInBytes + 1;

            // Final blob we return = version + HMAC + iv + cipherText
            const int hmacStartIndex = 1;
            int authenticationTagLen = hasAuthenticationTag ? _KeySizeInBytes : 0;
            int ivStartIndex = hmacStartIndex + authenticationTagLen;
            int cipherStartIndex = ivStartIndex + _BlockSizeInBytes; // this is where hmac starts.

            // Output buffer size = size of VersionByte + Authentication Tag + IV + cipher Text blocks.
            int outputBufSize = sizeof(byte) + authenticationTagLen + iv.Length + (numBlocks*_BlockSizeInBytes);
            byte[] outBuffer = new byte[outputBufSize];

            // Store the version and IV rightaway
            outBuffer[0] = _algorithmVersion;
            Buffer.BlockCopy(iv, 0, outBuffer, ivStartIndex, iv.Length);

            AesCryptoServiceProvider aesAlg;

            // Try to get a provider from the pool.
            // If no provider is available, create a new one.
            if (!_cryptoProviderPool.TryDequeue(out aesAlg)) {
                aesAlg = new AesCryptoServiceProvider();

                try {
                    // Set various algorithm properties
                    aesAlg.Key = _columnEncryptionKey.EncryptionKey;
                    aesAlg.Mode = _cipherMode;
                    aesAlg.Padding = _paddingMode;
                }
                catch (Exception) {
                    if (aesAlg != null) {
                        aesAlg.Dispose();
                    }

                    throw;
                }
            }

            try {
                // Always set the IV since it changes from cell to cell.
                aesAlg.IV = iv;

                // Compute CipherText and authentication tag in a single pass
                using (ICryptoTransform encryptor = aesAlg.CreateEncryptor()) {
                    Debug.Assert(encryptor.CanTransformMultipleBlocks, "AES Encryptor can transform multiple blocks");
                    int count = 0;
                    int cipherIndex = cipherStartIndex; // this is where cipherText starts
                    if (numBlocks > 1) {
                        count = (numBlocks - 1) * _BlockSizeInBytes;
                        cipherIndex += encryptor.TransformBlock(plainText, 0, count, outBuffer, cipherIndex);
                    }

                    byte[] buffTmp = encryptor.TransformFinalBlock(plainText, count, plainText.Length - count); // done encrypting
                    Buffer.BlockCopy(buffTmp, 0, outBuffer, cipherIndex, buffTmp.Length);
                    cipherIndex += buffTmp.Length;
                }

                if (hasAuthenticationTag) {
                    using (HMACSHA256 hmac = new HMACSHA256(_columnEncryptionKey.MACKey)) {
                        Debug.Assert(hmac.CanTransformMultipleBlocks, "HMAC can't transform multiple blocks");
                        hmac.TransformBlock(_version, 0, _version.Length, _version, 0);
                        hmac.TransformBlock(iv, 0, iv.Length, iv, 0);

                        // Compute HMAC on final block
                        hmac.TransformBlock(outBuffer, cipherStartIndex, numBlocks * _BlockSizeInBytes, outBuffer, cipherStartIndex);
                        hmac.TransformFinalBlock(_versionSize, 0, _versionSize.Length);
                        byte[] hash = hmac.Hash;
                        Debug.Assert(hash.Length >= authenticationTagLen, "Unexpected hash size");
                        Buffer.BlockCopy(hash, 0, outBuffer, hmacStartIndex, authenticationTagLen);
                    }
                }
            }
            finally {
                // Return the provider to the pool.
                _cryptoProviderPool.Enqueue(aesAlg);
            }

            return outBuffer;
        }