public void Can_Send_Encrypted_Message()
        {
            var client = new JsonServiceClient(Config.AbsoluteBaseUri);

            var request = new HelloSecure { Name = "World" };

            var aes = new AesManaged { KeySize = AesUtils.KeySize };

            var aesKeyBytes = aes.Key.Combine(aes.IV);
            var rsaEncAesKeyBytes = RsaUtils.Encrypt(aesKeyBytes, SecureConfig.PublicKeyXml);

            var requestBody = typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedMessage = new EncryptedMessage
            {
                SymmetricKeyEncrypted = Convert.ToBase64String(rsaEncAesKeyBytes),
                EncryptedBody = AesUtils.Encrypt(requestBody, aes.Key, aes.IV)
            };
            var encResponse = client.Post(encryptedMessage);

            var responseJson = AesUtils.Decrypt(encResponse.EncryptedBody, aes.Key, aes.IV);
            var response = responseJson.FromJson<HelloSecureResponse>();

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
        public void Can_Send_Encrypted_Message()
        {
            var client = CreateClient();

            var request = new HelloSecure { Name = "World" };

            var aes = new AesManaged { KeySize = AesUtils.KeySize };

            var aesKeyBytes = aes.Key.Combine(aes.IV);
            var rsaEncAesKeyBytes = RsaUtils.Encrypt(aesKeyBytes, SecureConfig.PublicKeyXml);

            var timestamp = DateTime.UtcNow.ToUnixTime();

            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(rsaEncAesKeyBytes),
                EncryptedBody = AesUtils.Encrypt(requestBody, aes.Key, aes.IV)
            };
            var encResponse = client.Post(encryptedMessage);

            var responseJson = AesUtils.Decrypt(encResponse.EncryptedBody, aes.Key, aes.IV);
            var response = responseJson.FromJson<HelloSecureResponse>();

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
    public void Can_Send_Encrypted_Message()
    {
        var client = new JsonServiceClient(Config.AbsoluteBaseUri);

        var request = new HelloSecure {
            Name = "World"
        };
        var encRequest = RsaUtils.Encrypt(request.ToJson(), SecureConfig.PublicKeyXml);

        var encResponse = client.Post(new BasicEncryptedMessage
        {
            OperationName = typeof(HelloSecure).Name,
            EncryptedBody = encRequest
        });

        var responseJson = RsaUtils.Decrypt(encResponse.EncryptedBody, SecureConfig.PrivateKeyXml);
        var response     = responseJson.FromJson <HelloSecureResponse>();

        Assert.That(response.Result, Is.EqualTo("Hello, World!"));
    }
    public void Does_Hybrid_RSA_Crypt_and_Auth_AES_with_HMAC_SHA256()
    {
        var request = new HelloSecure {
            Name = "World"
        };
        var timestamp = DateTime.UtcNow.ToUnixTime();
        var msg       = timestamp + " POST " + request.GetType().Name + " " + request.ToJson();
        var msgBytes  = msg.ToUtf8Bytes();

        AesUtils.CreateCryptAuthKeysAndIv(out var cryptKey, out var authKey, out var iv);

        var encryptedBytes = AesUtils.Encrypt(msgBytes, cryptKey, iv);

        var decryptedBytes = AesUtils.Decrypt(encryptedBytes, cryptKey, iv);

        Assert.That(decryptedBytes, Is.EquivalentTo(msgBytes));

        var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

        var cryptAuthKeys = cryptKey.Combine(authKey);

        var rsaEncCryptAuthKeys     = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
        var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

        var decryptedMsg = ValidateAndDecrypt(authRsaEncCryptAuthKeys, authEncryptedBytes);

        var parts = decryptedMsg.SplitOnFirst(' ');

        Assert.That(long.Parse(parts[0]), Is.EqualTo(timestamp));

        parts = parts[1].SplitOnFirst(' ');
        Assert.That(parts[0], Is.EqualTo("POST"));

        parts = parts[1].SplitOnFirst(' ');
        Assert.That(parts[0], Is.EqualTo(request.GetType().Name));

        var decryptedJson    = parts[1];
        var decryptedRequest = decryptedJson.FromJson <HelloSecure>();

        Assert.That(decryptedRequest.Name, Is.EqualTo(request.Name));
    }
        public void Does_throw_on_replayed_messages()
        {
            var client = CreateClient();

            var request = new HelloSecure { Name = "World" };

            var aes = new AesManaged { KeySize = AesUtils.KeySize };

            var aesKeyBytes = aes.Key.Combine(aes.IV);
            var rsaEncAesKeyBytes = RsaUtils.Encrypt(aesKeyBytes, SecureConfig.PublicKeyXml);

            var timestamp = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(rsaEncAesKeyBytes),
                EncryptedBody = AesUtils.Encrypt(requestBody, aes.Key, aes.IV)
            };
            var encResponse = client.Post(encryptedMessage);

            try
            {
                client.Post(encryptedMessage);

                Assert.Fail("Should throw");
            }
            catch (WebServiceException ex)
            {
                ex.StatusDescription.Print();

                var errorResponse = (EncryptedMessageResponse)ex.ResponseDto;
                var responseJson = AesUtils.Decrypt(errorResponse.EncryptedBody, aes.Key, aes.IV);
                var response = responseJson.FromJson<ErrorResponse>();
                Assert.That(response.ResponseStatus.Message, Is.EqualTo("Nonce already seen"));
            }
        }
        public void Does_Hybrid_RSA_SHA512_AES_MasterKey_and_HmacSha256()
        {
            var request = new HelloSecure { Name = "World" };
            var msgBytes = request.ToJson().ToUtf8Bytes();

            byte[] masterKey, iv;
            AesUtils.CreateKeyAndIv(out masterKey, out iv);

            var sha512KeyBytes = masterKey.ToSha512HashBytes();

            var cryptKey = new byte[sha512KeyBytes.Length / 2];
            var authKey = new byte[sha512KeyBytes.Length / 2];

            Buffer.BlockCopy(sha512KeyBytes, 0, cryptKey, 0, cryptKey.Length);
            Buffer.BlockCopy(sha512KeyBytes, cryptKey.Length, authKey, 0, authKey.Length);

            var encryptedBytes = AesUtils.Encrypt(msgBytes, cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var aesKeyNonceBytes = iv.Combine(masterKey);
            var rsaEncAesKeyNonceBytes = RsaUtils.Encrypt(aesKeyNonceBytes, SecureConfig.PublicKeyXml);

            var json = ValidateAndDecryptWithMasterKey(rsaEncAesKeyNonceBytes, authEncryptedBytes);

            var fromJson = json.FromJson<HelloSecure>();

            Assert.That(fromJson.Name, Is.EqualTo(request.Name));
        }
        public void Does_Hybrid_RSA_Crypt_and_Auth_AES_with_HMAC_SHA256()
        {
            var request = new HelloSecure { Name = "World" };
            var timestamp = DateTime.UtcNow.ToUnixTime();
            var msg = timestamp + " POST " + request.GetType().Name + " " + request.ToJson();
            var msgBytes = msg.ToUtf8Bytes();

            byte[] cryptKey, authKey, iv;
            AesUtils.CreateCryptAuthKeysAndIv(out cryptKey, out authKey, out iv);

            var encryptedBytes = AesUtils.Encrypt(msgBytes, cryptKey, iv);

            var decryptedBytes = AesUtils.Decrypt(encryptedBytes, cryptKey, iv);
            Assert.That(decryptedBytes, Is.EquivalentTo(msgBytes));

            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var decryptedMsg = ValidateAndDecrypt(authRsaEncCryptAuthKeys, authEncryptedBytes);
            
            var parts = decryptedMsg.SplitOnFirst(' ');
            Assert.That(long.Parse(parts[0]), Is.EqualTo(timestamp));

            parts = parts[1].SplitOnFirst(' ');
            Assert.That(parts[0], Is.EqualTo("POST"));

            parts = parts[1].SplitOnFirst(' ');
            Assert.That(parts[0], Is.EqualTo(request.GetType().Name));

            var decryptedJson = parts[1];
            var decryptedRequest = decryptedJson.FromJson<HelloSecure>();

            Assert.That(decryptedRequest.Name, Is.EqualTo(request.Name));
        }
        public void Can_Encrypt_and_Decrypt_with_AES_bytes()
        {
            var msg = new HelloSecure { Name = "World" };

            byte[] cryptKey, iv;
            AesUtils.CreateKeyAndIv(out cryptKey, out iv);

            var encryptedBytes = AesUtils.Encrypt(msg.ToJson().ToUtf8Bytes(), cryptKey, iv);

            var msgBytes = AesUtils.Decrypt(encryptedBytes, cryptKey, iv);

            var decryptedMsg = msgBytes.FromUtf8Bytes().FromJson<HelloSecure>();

            Assert.That(decryptedMsg.Name, Is.EqualTo(msg.Name));
        }
        public void Does_throw_on_replayed_messages()
        {
            var client = CreateClient();

            var request = new HelloSecure { Name = "World" };

            byte[] cryptKey, iv;
            AesUtils.CreateKeyAndIv(out cryptKey, out iv);

            byte[] authKey = AesUtils.CreateKey();

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var timestamp = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedBytes = AesUtils.Encrypt(requestBody.ToUtf8Bytes(), cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(authRsaEncCryptAuthKeys),
                EncryptedBody = Convert.ToBase64String(authEncryptedBytes),
            };

            var encResponse = client.Post(encryptedMessage);

            try
            {
                client.Post(encryptedMessage);

                Assert.Fail("Should throw");
            }
            catch (WebServiceException ex)
            {
                ex.StatusDescription.Print();

                var errorResponse = (EncryptedMessageResponse)ex.ResponseDto;

                authEncryptedBytes = Convert.FromBase64String(errorResponse.EncryptedBody);
                if (!HmacUtils.Verify(authEncryptedBytes, authKey))
                    throw new Exception("EncryptedBody is Invalid");

                var responseBytes = HmacUtils.DecryptAuthenticated(authEncryptedBytes, cryptKey);
                var responseJson = responseBytes.FromUtf8Bytes();
                var response = responseJson.FromJson<ErrorResponse>();
                Assert.That(response.ResponseStatus.Message, Is.EqualTo("Nonce already seen"));
            }
        }
        public void Can_Send_Encrypted_Message()
        {
            var client = CreateClient();

            var request = new HelloSecure { Name = "World" };

            byte[] cryptKey, authKey, iv;
            AesUtils.CreateCryptAuthKeysAndIv(out cryptKey, out authKey, out iv);

            var cryptAuthKeys = cryptKey.Combine(authKey);

            var rsaEncCryptAuthKeys = RsaUtils.Encrypt(cryptAuthKeys, SecureConfig.PublicKeyXml);
            var authRsaEncCryptAuthKeys = HmacUtils.Authenticate(rsaEncCryptAuthKeys, authKey, iv);

            var timestamp = DateTime.UtcNow.ToUnixTime();
            var requestBody = timestamp + " POST " + typeof(HelloSecure).Name + " " + request.ToJson();

            var encryptedBytes = AesUtils.Encrypt(requestBody.ToUtf8Bytes(), cryptKey, iv);
            var authEncryptedBytes = HmacUtils.Authenticate(encryptedBytes, authKey, iv);

            var encryptedMessage = new EncryptedMessage
            {
                EncryptedSymmetricKey = Convert.ToBase64String(authRsaEncCryptAuthKeys),
                EncryptedBody = Convert.ToBase64String(authEncryptedBytes),
            };

            var encResponse = client.Post(encryptedMessage);

            authEncryptedBytes = Convert.FromBase64String(encResponse.EncryptedBody);

            if (!HmacUtils.Verify(authEncryptedBytes, authKey))
                throw new Exception("Invalid EncryptedBody");

            var decryptedBytes = HmacUtils.DecryptAuthenticated(authEncryptedBytes, cryptKey);

            var responseJson = decryptedBytes.FromUtf8Bytes();
            var response = responseJson.FromJson<HelloSecureResponse>();

            Assert.That(response.Result, Is.EqualTo("Hello, World!"));
        }
 public object Any(HelloSecure request) => new HelloResponse
 {
     Result = $"Hello, {request.Name}!"
 };