/// <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); } }
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); }