public EncryptedPacket EncryptData(
			byte[] original, RSAWithRSAParameterKey rsaParams, DigitalSignature digitalSignature)
		{
			const int sessionKeyLength = 32;
			const int ivLength = 16;

			byte[] sessionKey = _aes.GenerateRandomNumber(sessionKeyLength);
			EncryptedPacket encryptedPacket = new EncryptedPacket { Iv = _aes.GenerateRandomNumber(ivLength) };
			encryptedPacket.EncryptedData = _aes.Encrypt(original, sessionKey, encryptedPacket.Iv);
			encryptedPacket.EncryptedSessionKey = rsaParams.EncryptData(sessionKey);

			using (var hmac = new HMACSHA256(sessionKey))
			{
				encryptedPacket.Hmac = hmac.ComputeHash(encryptedPacket.EncryptedData);
			}
			encryptedPacket.Signature = digitalSignature.SignData(encryptedPacket.Hmac);

			return encryptedPacket;
		}
		public byte[] DecryptData(
			EncryptedPacket encryptedPacket, RSAWithRSAParameterKey rsaParams, DigitalSignature digitalSignature)
		{
			var decryptedSessionKey = rsaParams.DecryptData(encryptedPacket.EncryptedSessionKey);
			using (var hmac = new HMACSHA256(decryptedSessionKey))
			{
				var hmacToCheck = hmac.ComputeHash(encryptedPacket.EncryptedData);
				if (!Compare(encryptedPacket.Hmac, hmacToCheck))
					throw new CryptographicException("HMAC for decryption does not match encrypted packet.");

				if (!digitalSignature.VerifySignature(encryptedPacket.Hmac, encryptedPacket.Signature))
					throw new CryptographicException("Digital Signature can not be verified.");
			}

			var decryptedData = 
				_aes.Decrypt(encryptedPacket.EncryptedData, decryptedSessionKey, encryptedPacket.Iv);

			return decryptedData;
		}