/// <summary> /// Encrypt RestSharp request payloads. /// </summary> /// <param name="request">A RestSharp request object</param> public void InterceptRequest(IRestRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } try { // Check request actually has a payload var bodyParam = request.Parameters.FirstOrDefault(param => param.Type == ParameterType.RequestBody); if (bodyParam == null) { // Nothing to encrypt return; } var payload = bodyParam.Value.ToString(); if (string.IsNullOrEmpty(payload)) { // Nothing to encrypt return; } // Encrypt fields & update headers string encryptedPayload; if (_config.UseHttpHeaders()) { // Generate encryption params and add them as HTTP headers var parameters = FieldLevelEncryptionParams.Generate(_config); UpdateRequestHeader(request, _config.IvHeaderName, parameters.IvValue); UpdateRequestHeader(request, _config.EncryptedKeyHeaderName, parameters.EncryptedKeyValue); UpdateRequestHeader(request, _config.EncryptionCertificateFingerprintHeaderName, _config.EncryptionCertificateFingerprint); UpdateRequestHeader(request, _config.EncryptionKeyFingerprintHeaderName, _config.EncryptionKeyFingerprint); UpdateRequestHeader(request, _config.OaepPaddingDigestAlgorithmHeaderName, parameters.OaepPaddingDigestAlgorithmValue); encryptedPayload = FieldLevelEncryption.EncryptPayload(payload, _config, parameters); } else { // Encryption params will be stored in the payload encryptedPayload = FieldLevelEncryption.EncryptPayload(payload, _config); } // Update body and content length bodyParam.Value = encryptedPayload; UpdateRequestHeader(request, "Content-Length", encryptedPayload.Length); } catch (EncryptionException) { throw; } catch (Exception e) { throw new EncryptionException("Failed to intercept and encrypt request!", e); } }
public void TestWrapUnwrapSecretKey_ShouldReturnTheOriginalKey() { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder().Build(); var originalKeyBytes = Convert.FromBase64String("mZzmzoURXI3Vk0vdsPkcFw=="); // WHEN var wrappedKeyBytes = FieldLevelEncryptionParams.WrapSecretKey(config, originalKeyBytes); var unwrappedKeyBytes = FieldLevelEncryptionParams.UnwrapSecretKey(config, wrappedKeyBytes, config.OaepPaddingDigestAlgorithm); // THEN Assert.IsTrue(originalKeyBytes.SequenceEqual(unwrappedKeyBytes)); }
/// <summary> /// Decrypt RestSharp response payloads. /// </summary> /// <param name="response">A RestSharp response object</param> public void InterceptResponse(IRestResponse response) { if (response == null) { throw new ArgumentNullException(nameof(response)); } try { // Read response payload var encryptedPayload = response.Content; if (string.IsNullOrEmpty(encryptedPayload)) { // Nothing to decrypt return; } // Decrypt fields & update headers string decryptedPayload; if (_config.UseHttpHeaders()) { // Read encryption params from HTTP headers and delete headers var ivValue = ReadAndRemoveHeader(response, _config.IvHeaderName); var encryptedKeyValue = ReadAndRemoveHeader(response, _config.EncryptedKeyHeaderName); var oaepPaddingDigestAlgorithmValue = ReadAndRemoveHeader(response, _config.OaepPaddingDigestAlgorithmHeaderName); ReadAndRemoveHeader(response, _config.EncryptionCertificateFingerprintHeaderName); ReadAndRemoveHeader(response, _config.EncryptionKeyFingerprintHeaderName); var parameters = new FieldLevelEncryptionParams(_config, ivValue, encryptedKeyValue, oaepPaddingDigestAlgorithmValue); decryptedPayload = FieldLevelEncryption.DecryptPayload(encryptedPayload, _config, parameters); } else { // Encryption params are stored in the payload decryptedPayload = FieldLevelEncryption.DecryptPayload(encryptedPayload, _config); } // Update body and content length var contentTypeInfo = response.GetType().GetTypeInfo().GetDeclaredField("_content"); contentTypeInfo.SetValue(response, new Lazy <string>(() => decryptedPayload)); } catch (EncryptionException) { throw; } catch (Exception e) { throw new EncryptionException("Failed to intercept and decrypt response!", e); } }
public void TestGenerate_Nominal() { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder().Build(); // WHEN var parameters = FieldLevelEncryptionParams.Generate(config); // THEN Assert.IsNotNull(parameters.IvValue); Assert.IsNotNull(parameters.GetIvBytes()); Assert.IsNotNull(parameters.EncryptedKeyValue); Assert.IsNotNull(parameters.GetSecretKeyBytes()); Assert.AreEqual("SHA256", parameters.OaepPaddingDigestAlgorithmValue); }
public void TestUnwrapSecretKey_InteroperabilityTest_OaepSha256() { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder() .WithOaepPaddingDigestAlgorithm("SHA-256") .Build(); const string wrappedKey = "ZLB838BRWW2/BtdFFAWBRYShw/gBxXSwItpxEZ9zaSVEDHo7n+SyVYU7mayd+9vHkR8OdpqwpXM68t0VOrWI8LD8A2pRaYx8ICyhVFya4OeiWlde05Rhsk+TNwwREPbiw1RgjT8aedRJJYbAZdLb9XEI415Kb/UliHyvsdHMb6vKyYIjUHB/pSGAAmgds56IhIJGfvnBLPZfSHmGgiBT8WXLRuuf1v48aIadH9S0FfoyVGTaLYr+2eznSTAFC0ZBnzebM3mQI5NGQNviTnEJ0y+uZaLE/mthiKgkv1ZybyDPx2xJK2n05sNzfIWKmnI/SOb65RZLlo1Q+N868l2m9g=="; var wrappedKeyBytes = Convert.FromBase64String(wrappedKey); // WHEN var unwrappedKeyBytes = FieldLevelEncryptionParams.UnwrapSecretKey(config, wrappedKeyBytes, config.OaepPaddingDigestAlgorithm); // THEN var expectedKeyBytes = Convert.FromBase64String("mZzmzoURXI3Vk0vdsPkcFw=="); Assert.IsTrue(expectedKeyBytes.SequenceEqual(unwrappedKeyBytes)); }
public void TestUnwrapSecretKey_InteroperabilityTest_OaepSha512() { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder() .WithOaepPaddingDigestAlgorithm("SHA-512") .Build(); const string wrappedKey = "RuruMYP5rG6VP5vS4kVznIrSOjUzXyOhtD7bYlVqwniWTvxxZC73UDluwDhpLwX5QJCsCe8TcwGiQRX1u+yWpBveHDRmDa03hrc3JRJALEKPyN5tnt5w7aI4dLRnLuNoXbYoTSc4V47Z3gaaK6q2rEjydx2sQ/SyVmeUJN7NgxkhtHTyVWTymEM1ythL+AaaQ5AaXedhpWKhG06XYZIX4KV7T9cHEn+See6RVGGB2RUPHBJjrxJo5JoVSfnWN0gkTMyuwbmVaTWfsowbvh8GFibFT7h3uXyI3b79NiauyB7scXp9WidGues3MrTx4dKZrSbs3uHxzPKmCDZimuKfwg=="; var wrappedKeyBytes = Convert.FromBase64String(wrappedKey); // WHEN var unwrappedKeyBytes = FieldLevelEncryptionParams.UnwrapSecretKey(config, wrappedKeyBytes, config.OaepPaddingDigestAlgorithm); // THEN var expectedKeyBytes = Convert.FromBase64String("mZzmzoURXI3Vk0vdsPkcFw=="); Assert.IsTrue(expectedKeyBytes.SequenceEqual(unwrappedKeyBytes)); }
public void TestGetSecretKeyBytes_ShouldThrowEncryptionException_WhenFailsToReadEncryptedKey() { try { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder().Build(); var parameters = new FieldLevelEncryptionParams(config, null, "INVALID VALUE"); // WHEN var secretKeyBytes = parameters.GetSecretKeyBytes(); Assert.Fail($"Unexpected {secretKeyBytes}"); } catch (Exception e) { // THEN Assert.AreEqual("Failed to decode and unwrap the provided secret key value!", e.Message); throw; } }
public void TestGetIvBytes_ShouldThrowEncryptionException_WhenFailsToDecodeIV() { try { // GIVEN var config = TestUtils.GetTestFieldLevelEncryptionConfigBuilder().Build(); var parameters = new FieldLevelEncryptionParams(config, "INVALID VALUE", null); // WHEN var ivBytes = parameters.GetIvBytes(); Assert.Fail($"Unexpected {ivBytes}"); } catch (Exception e) { // THEN Assert.AreEqual("Failed to decode the provided IV value!", e.Message); throw; } }
/// <summary> /// Decrypt a RestSharp response payload /// </summary> /// <param name="response">A RestSharp response object</param> /// <param name="encryptedPayload">The encrypted payload to be decrypted</param> /// <returns>The decrypted payload</returns> internal override string DecryptPayload(IRestResponse response, string encryptedPayload) { // Decrypt fields & update headers string decryptedPayload; if (_config.UseHttpHeaders()) { // Read encryption params from HTTP headers and delete headers var ivValue = ReadAndRemoveHeader(response, _config.IvHeaderName); var encryptedKeyValue = ReadAndRemoveHeader(response, _config.EncryptedKeyHeaderName); var oaepPaddingDigestAlgorithmValue = ReadAndRemoveHeader(response, _config.OaepPaddingDigestAlgorithmHeaderName); ReadAndRemoveHeader(response, _config.EncryptionCertificateFingerprintHeaderName); ReadAndRemoveHeader(response, _config.EncryptionKeyFingerprintHeaderName); var parameters = new FieldLevelEncryptionParams(_config, ivValue, encryptedKeyValue, oaepPaddingDigestAlgorithmValue); decryptedPayload = FieldLevelEncryption.DecryptPayload(encryptedPayload, _config, parameters); } else { // Encryption params are stored in the payload decryptedPayload = FieldLevelEncryption.DecryptPayload(encryptedPayload, _config); } return(decryptedPayload); }
/// <summary> /// Encrypt a RestSharp request payload. /// </summary> /// <param name="request">A RestSharp request object</param> /// <param name="payload">The payload to be encrypted</param> /// <returns>The encrypted payload</returns> internal override string EncryptPayload(IRestRequest request, string payload) { // Encrypt fields & update headers string encryptedPayload; if (_config.UseHttpHeaders()) { // Generate encryption params and add them as HTTP headers var parameters = FieldLevelEncryptionParams.Generate(_config); UpdateRequestHeader(request, _config.IvHeaderName, parameters.IvValue); UpdateRequestHeader(request, _config.EncryptedKeyHeaderName, parameters.EncryptedKeyValue); UpdateRequestHeader(request, _config.EncryptionCertificateFingerprintHeaderName, _config.EncryptionCertificateFingerprint); UpdateRequestHeader(request, _config.EncryptionKeyFingerprintHeaderName, _config.EncryptionKeyFingerprint); UpdateRequestHeader(request, _config.OaepPaddingDigestAlgorithmHeaderName, parameters.OaepPaddingDigestAlgorithmValue); encryptedPayload = FieldLevelEncryption.EncryptPayload(payload.ToString(), _config, parameters); } else { // Encryption params will be stored in the payload encryptedPayload = FieldLevelEncryption.EncryptPayload(payload.ToString(), _config); } return(encryptedPayload); }