/// <summary>
        /// Generate encryption parameters.
        /// </summary>
        /// <exception cref="EncryptionException"/>
        public static FieldLevelEncryptionParams Generate(FieldLevelEncryptionConfig config)
        {
            // Generate a random IV
            var ivBytes = GenerateIv();
            var ivValue = EncodingUtils.EncodeBytes(ivBytes, config.ValueEncoding);

            // Generate an AES secret key
            var secretKeyBytes = GenerateSecretKey();

            // Encrypt the secret key
            var encryptedSecretKeyBytes = RsaEncryption.WrapSecretKey(config.EncryptionCertificate.GetRSAPublicKey(), secretKeyBytes, config.OaepPaddingDigestAlgorithm);
            var encryptedKeyValue       = EncodingUtils.EncodeBytes(encryptedSecretKeyBytes, config.ValueEncoding);

            // Compute the OAEP padding digest algorithm
            var oaepPaddingDigestAlgorithmValue = config.OaepPaddingDigestAlgorithm.Replace("-", string.Empty);

            return(new FieldLevelEncryptionParams
            {
                IvValue = ivValue,
                EncryptedKeyValue = encryptedKeyValue,
                OaepPaddingDigestAlgorithmValue = oaepPaddingDigestAlgorithmValue,
                Config = config,
                SecretKeyBytes = secretKeyBytes,
                IvBytes = ivBytes
            });
        }
 private void ComputeEncryptionCertificateFingerprintWhenNeeded()
 {
     try
     {
         if (_encryptionCertificate == null || !string.IsNullOrEmpty(_encryptionCertificateFingerprint))
         {
             // No encryption certificate set or certificate fingerprint already provided
             return;
         }
         var certificateFingerprintBytes = Sha256Digest(_encryptionCertificate.RawData);
         _encryptionCertificateFingerprint = EncodingUtils.EncodeBytes(certificateFingerprintBytes, FieldValueEncoding.Hex);
     }
     catch (Exception e)
     {
         throw new EncryptionException("Failed to compute encryption certificate fingerprint!", e);
     }
 }
Example #3
0
        private static JToken EncryptPayloadPath(JToken payloadToken, string jsonPathIn, string jsonPathOut,
                                                 FieldLevelEncryptionConfig config, FieldLevelEncryptionParams parameters)
        {
            if (payloadToken == null)
            {
                throw new ArgumentNullException(nameof(payloadToken));
            }
            if (jsonPathIn == null)
            {
                throw new ArgumentNullException(nameof(jsonPathIn));
            }
            if (jsonPathOut == null)
            {
                throw new ArgumentNullException(nameof(jsonPathOut));
            }

            var inJsonToken = payloadToken.SelectToken(jsonPathIn);

            if (inJsonToken == null)
            {
                // Nothing to encrypt
                return(payloadToken);
            }

            if (parameters == null)
            {
                // Generate encryption params
                parameters = FieldLevelEncryptionParams.Generate(config);
            }

            // Encrypt data at the given JSON path
            var inJsonString        = JsonUtils.SanitizeJson(inJsonToken.ToString());
            var inJsonBytes         = Encoding.ASCII.GetBytes(inJsonString);
            var encryptedValueBytes = EncryptBytes(parameters.GetSecretKeyBytes(), parameters.GetIvBytes(), inJsonBytes);
            var encryptedValue      = EncodingUtils.EncodeBytes(encryptedValueBytes, config.ValueEncoding);

            // Delete data in clear
            if (!"$".Equals(jsonPathIn))
            {
                inJsonToken.Parent.Remove();
            }
            else
            {
                // We need a JObject (we can't work with a JArray for instance)
                payloadToken = JObject.Parse("{}");
            }

            // Add encrypted data and encryption fields at the given JSON path
            JsonUtils.CheckOrCreateOutObject(payloadToken, jsonPathOut);
            var outJsonToken = payloadToken.SelectToken(jsonPathOut) as JObject;

            JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.EncryptedValueFieldName, encryptedValue);
            if (!string.IsNullOrEmpty(config.IvFieldName))
            {
                JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.IvFieldName, parameters.IvValue);
            }
            if (!string.IsNullOrEmpty(config.EncryptedKeyFieldName))
            {
                JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.EncryptedKeyFieldName, parameters.EncryptedKeyValue);
            }
            if (!string.IsNullOrEmpty(config.EncryptionCertificateFingerprintFieldName))
            {
                JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.EncryptionCertificateFingerprintFieldName, config.EncryptionCertificateFingerprint);
            }
            if (!string.IsNullOrEmpty(config.EncryptionKeyFingerprintFieldName))
            {
                JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.EncryptionKeyFingerprintFieldName, config.EncryptionKeyFingerprint);
            }
            if (!string.IsNullOrEmpty(config.OaepPaddingDigestAlgorithmFieldName))
            {
                JsonUtils.AddOrReplaceJsonKey(outJsonToken, config.OaepPaddingDigestAlgorithmFieldName, parameters.OaepPaddingDigestAlgorithmValue);
            }

            return(payloadToken);
        }