public byte[] DecryptData(EncryptedPacket encryptedPacket, RSAParameters privateEncryptionKey, RSAParameters publicSigningKey)
        {
            var decryptedSessionKey = _rsaEncryption.DecryptData(encryptedPacket.EncryptedSessionKey, privateEncryptionKey);

            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 (!_signature.VerifySignature(encryptedPacket.Hmac, encryptedPacket.Signature, publicSigningKey))
                {
                    throw new CryptographicException(
                              "Digital Signature can not be verified.");
                }
            }

            return(_aesEncryption.Decrypt(encryptedPacket.EncryptedData,
                                          decryptedSessionKey,
                                          encryptedPacket.Iv));
        }
        public EncryptedPacket EncryptData(byte[] original, RSAParameters publicEncryptionKey, RSAParameters privateSigningKey)
        {
            var sessionKey      = GenerateRandomNumber(32);
            var vector          = GenerateRandomNumber(16);
            var encryptedPacket = new EncryptedPacket
            {
                Iv                  = vector,
                EncryptedData       = _aesEncryption.Encrypt(original, sessionKey, vector),
                EncryptedSessionKey = _rsaEncryption.EncryptData(sessionKey, publicEncryptionKey)
            };

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

            encryptedPacket.Signature = _signature.SignData(encryptedPacket.Hmac, privateSigningKey);

            return(encryptedPacket);
        }