Exemplo n.º 1
0
        // public AnonymizerRule[] DicomVRRules { get; private set; } = null;

        public AnonymizerConfigurationManager(AnonymizerConfiguration configuration)
        {
            configuration.GenerateDefaultParametersIfNotConfigured();
            _configuration = configuration;
            DicomTagRules  = _configuration.DicomTagRules.Select(entry => AnonymizationDicomTagRule.CreateAnonymizationDICOMRule(entry)).ToArray();
            // DicomVRRules = _configuration.DicomVRRules.Select(entry => AnonymizationDicomTagRule.CreateAnonymizationFhirPathRule(entry)).ToArray();
        }
Exemplo n.º 2
0
        public void ShowCaseTest()
        {
            Assert.IsTrue(em.IsValid());
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            // Image there is a service provider to analyse the verbrauchs data but he shouldn't know about the location data.
            // Yet it should still be possible to map the results back to my original data. So hashing seems like a good approach.
            var config = new AnonymizerConfiguration();

            config.SetOption(BO4E.meta.DataCategory.POD, AnonymizerApproach.HASH);
            byte[] salt = new Byte[100];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            rng.GetBytes(salt);
            config.hashingSalt = Convert.ToBase64String(salt); // Some random but not necessarily secret salt;
            Energiemenge anonymizedEm;

            using (Anonymizer anon = new Anonymizer(config))
            {
                anonymizedEm = anon.ApplyOperations <Energiemenge>(em);
            }
            Debug.WriteLine($"No one knowing only {anonymizedEm.LokationsId} actually means {em.LokationsId}");
            Assert.AreNotEqual(em.LokationsId, anonymizedEm.LokationsId);
            Debug.WriteLine($"But it won't cause any problems in satellite systems because the data is still there (!=null) and the business object is still valid.");
            Assert.IsNotNull(anonymizedEm.LokationsId);
            Assert.IsTrue(anonymizedEm.IsValid());
        }
        public void GivenConfigWithParameter_GenerateDefaultParametersIfNotConfigured_ParametersShouldNotOverwrite()
        {
            var configuration = new AnonymizerConfiguration();

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);

            configuration = new AnonymizerConfiguration()
            {
                ParameterConfiguration = new ParameterConfiguration()
                {
                    DateShiftKey             = "123",
                    PresidioAnonymizerUrl    = "http://127.0.0.1:3000",
                    PresidioAnalyzerUrl      = "http://127.0.0.1:3001",
                    PresidioAnalyzedLanguage = "es"
                }
            };

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.Equal("123", configuration.ParameterConfiguration.DateShiftKey);
            Assert.Equal("http://127.0.0.1:3000", configuration.ParameterConfiguration.PresidioAnonymizerUrl);
            Assert.Equal("http://127.0.0.1:3001", configuration.ParameterConfiguration.PresidioAnalyzerUrl);
            Assert.Equal("es", configuration.ParameterConfiguration.PresidioAnalyzedLanguage);
        }
Exemplo n.º 4
0
        public void TestCaginMeLos()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            var result = new Dictionary <string, string>()
            {
                { "DE0004096816110000000000000022591", null },
                { "DE0004946353300000000000001652988", null },
                { "DE00746663128OF000000000000010156", null },
                { "DE0004946307100000000000001312595", null },
            };
            var conf = new AnonymizerConfiguration();

            conf.SetOption(DataCategory.POD, AnonymizerApproach.HASH);

            using (Anonymizer anonymizer = new Anonymizer(conf))
            {
                foreach (var plaintextMeLoId in result.Keys.ToList())
                {
                    Messlokation melo = new Messlokation()
                    {
                        MesslokationsId = plaintextMeLoId
                    };
                    var hashedMelo = anonymizer.ApplyOperations <Messlokation>(melo);
                    result[plaintextMeLoId] = hashedMelo.MesslokationsId;
                }
            }
            var resultJson = JsonConvert.SerializeObject(result);
        }
Exemplo n.º 5
0
        public AnonymizerRuleFactoryTests()
        {
            var content = File.ReadAllText("Rules/settings.json");

            _configuration = JsonConvert.DeserializeObject <AnonymizerConfiguration>(content);
            _ruleFactory   = new AnonymizerRuleFactory(_configuration, new DicomProcessorFactory());
        }
        public AnonymizerConfigurationManager(AnonymizerConfiguration configuration)
        {
            _validator.Validate(configuration);
            configuration.GenerateDefaultParametersIfNotConfigured();

            _configuration = configuration;

            FhirPathRules = _configuration.FhirPathRules.Select(entry => AnonymizationFhirPathRule.CreateAnonymizationFhirPathRule(entry)).ToArray();
        }
        public AnonymizerRuleFactory(AnonymizerConfiguration configuration, IAnonymizerProcessorFactory processorFactory)
        {
            EnsureArg.IsNotNull(configuration, nameof(configuration));
            EnsureArg.IsNotNull(processorFactory, nameof(processorFactory));

            _defaultSettings  = configuration.DefaultSettings;
            _customSettings   = configuration.CustomSettings;
            _processorFactory = processorFactory;
        }
        public void TestAcInitial()
        {
            AnonymizerConfiguration ac = new AnonymizerConfiguration();

            Assert.IsTrue(ac.IsInitial());
            Assert.IsFalse(ac.ContainsNonKeepingOperations());
            ac.SetOption(DataCategory.ADDRESS, AnonymizerApproach.ENCRYPT);
            Assert.IsTrue(ac.ContainsNonKeepingOperations());
            Assert.IsFalse(ac.IsInitial());
        }
        public void TestAcSalt()
        {
            AnonymizerConfiguration ac = new AnonymizerConfiguration
            {
                hashingSalt = "UG9seWZvbiB6d2l0c2NoZXJuZCBhw59lbiBNw6R4Y2hlbnMgVsO2Z2VsIFLDvGJlbiwgSm9naHVydCB1bmQgUXVhcms="
            };

            Assert.IsTrue(ac.GetSalt().Length > 0);
            ac.hashingSalt = "   ";
            Assert.IsTrue(ac.GetSalt().Length == 0);
            ac.hashingSalt = null;
            Assert.IsTrue(ac.GetSalt().Length == 0);
        }
Exemplo n.º 10
0
        public void TestAnonymizeEnergiemengeHashing()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            Energiemenge em = new Energiemenge()
            {
                LokationsId      = "DE0123456789012345678901234567890",
                LokationsTyp     = BO4E.ENUM.Lokationstyp.MeLo,
                Energieverbrauch = new List <Verbrauch>()
                {
                    new Verbrauch()
                    {
                        Wert = 123.456M,
                        Wertermittlungsverfahren = BO4E.ENUM.Wertermittlungsverfahren.MESSUNG,
                        Startdatum   = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc),
                        Enddatum     = new DateTime(2019, 2, 1, 0, 0, 0, DateTimeKind.Utc),
                        Obiskennzahl = "1-2-3-4",
                        Einheit      = BO4E.ENUM.Mengeneinheit.KWH
                    }
                }
            };
            var conf = new AnonymizerConfiguration();

            conf.SetOption(DataCategory.POD, AnonymizerApproach.HASH);
            conf.SetOption(DataCategory.USER_PROPERTIES, AnonymizerApproach.HASH);
            Anonymizer anonymizer = new Anonymizer(conf);
            var        verbrauch2 = JsonConvert.DeserializeObject <Verbrauch>("{\"zw\":\"000000000000485549\",\"startdatum\":\"2018-03-24T01:45:00Z\",\"enddatum\":\"2018-03-24T02:00:00Z\",\"wert\":\"59\",\"status\":\"IU012\",\"obiskennzahl\":\"1-1:2.29.0\",\"wertermittlungsverfahren\":\"MESSUNG\",\"einheit\":\"KWH\"}");

            em.Energieverbrauch.Add(verbrauch2);

            // hash everything
            var result = anonymizer.ApplyOperations <Energiemenge>(em);

            Assert.IsNotNull(result);
            Assert.AreNotEqual(em.LokationsId, result.LokationsId);
            Assert.IsTrue(Messlokation.ValidateId(result.LokationsId));
            Assert.AreEqual(em.Energieverbrauch.Count, result.Energieverbrauch.Count);
            Assert.IsNotNull(result.Energieverbrauch[1].UserProperties["zw"]);
            Assert.AreNotEqual(em.Energieverbrauch[1].UserProperties["zw"].Value <string>(), result.Energieverbrauch[1].UserProperties["zw"].Value <string>());
            Assert.IsTrue(Anonymizer.HasHashedKey(result));

            // do not hash zw user property
            conf.unaffectedUserProperties.Add("zw");
            result = anonymizer.ApplyOperations <Energiemenge>(em);
            Assert.IsNotNull(result);
            Assert.AreNotEqual(em.LokationsId, result.LokationsId);
            Assert.IsTrue(Messlokation.ValidateId(result.LokationsId));
            Assert.AreEqual(em.Energieverbrauch.Count, result.Energieverbrauch.Count);
            Assert.IsNotNull(result.Energieverbrauch[1].UserProperties["zw"]);
            Assert.AreEqual(em.Energieverbrauch[1].UserProperties["zw"].Value <string>(), result.Energieverbrauch[1].UserProperties["zw"].Value <string>());
            Assert.IsTrue(Anonymizer.HasHashedKey(result));
        }
Exemplo n.º 11
0
        public void TestAnonymizeEnergiemengeEncryptionRoundtrip()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            Energiemenge em = new Energiemenge()
            {
                LokationsId      = "DE0123456789012345678901234567890",
                LokationsTyp     = BO4E.ENUM.Lokationstyp.MeLo,
                Energieverbrauch = new List <Verbrauch>()
                {
                    new Verbrauch()
                    {
                        Wert = 123.456M,
                        Wertermittlungsverfahren = BO4E.ENUM.Wertermittlungsverfahren.MESSUNG,
                        Obiskennzahl             = "1-2-3-4",
                        Einheit = BO4E.ENUM.Mengeneinheit.KWH
                    }
                }
            };

            //ENCRYPTION
            var encConf = new AnonymizerConfiguration();

            encConf.SetOption(DataCategory.POD, AnonymizerApproach.ENCRYPT);
            Energiemenge encryptedEm;

            using (Anonymizer anonymizer = new Anonymizer(encConf))
            {
                X509Certificate2 x509certPubl = new X509Certificate2(X509Certificate2.CreateFromCertFile("anonymizerTests/certificates/publicX509Cert.crt"));
                anonymizer.SetPublicKey(x509certPubl);
                encryptedEm = anonymizer.ApplyOperations <Energiemenge>(em);
            }

            //DECRYPTION
            var decConf = new AnonymizerConfiguration();

            decConf.SetOption(DataCategory.POD, AnonymizerApproach.DECRYPT);
            Energiemenge decryptedEm;

            using (Anonymizer decryptingAnonymizer = new Anonymizer(decConf))
            {
                AsymmetricCipherKeyPair keyPair;
                using (var reader = File.OpenText(@"anonymizerTests/certificates/privateKey.pem")) // file containing RSA PKCS1 private key
                {
                    keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject();
                }
                decryptingAnonymizer.SetPrivateKey(keyPair.Private);
                decryptedEm = decryptingAnonymizer.ApplyOperations <Energiemenge>(encryptedEm);
            }
            Assert.AreEqual(em.LokationsId, decryptedEm.LokationsId);
            Assert.IsFalse(Anonymizer.HasHashedKey(em));
        }
Exemplo n.º 12
0
        public void TestCompletenessReportHashing()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            CompletenessReport cr = new CompletenessReport()
            {
                LokationsId = "56789012345",
                Coverage    = 0.9M,
                Einheit     = BO4E.ENUM.Mengeneinheit.MWH,
                wertermittlungsverfahren = BO4E.ENUM.Wertermittlungsverfahren.MESSUNG,
                UserProperties           = new Dictionary <string, JToken>()
                {
                    { "anlage", "5012345678" },
                    { "profil", "123456" }
                }
            };

            Assert.IsTrue(cr.IsValid());
            var conf = new AnonymizerConfiguration();

            conf.SetOption(DataCategory.POD, AnonymizerApproach.HASH);
            conf.SetOption(DataCategory.USER_PROPERTIES, AnonymizerApproach.HASH);
            CompletenessReport hashedReport;

            using (Anonymizer anonymizer = new Anonymizer(conf))
            {
                hashedReport = anonymizer.ApplyOperations <CompletenessReport>(cr);
            }
            Assert.IsNotNull(hashedReport);
            Assert.AreNotEqual(cr.LokationsId, hashedReport.LokationsId);
            Assert.IsTrue(Marktlokation.ValidateId(hashedReport.LokationsId));
            Assert.IsNotNull(cr.UserProperties["anlage"]);
            Assert.AreNotEqual(cr.UserProperties["anlage"].Value <string>(), hashedReport.UserProperties["anlage"].Value <string>());
            Assert.IsNotNull(cr.UserProperties["profil"]);
            Assert.AreNotEqual(cr.UserProperties["profil"].Value <string>(), hashedReport.UserProperties["profil"].Value <string>());

            conf.hashingSalt = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
            CompletenessReport saltedReport;

            using (Anonymizer anonymizer = new Anonymizer(conf))
            {
                saltedReport = anonymizer.ApplyOperations <CompletenessReport>(cr);
            }
            Assert.IsNotNull(saltedReport.LokationsId);
            Assert.AreNotEqual(cr.LokationsId, saltedReport.LokationsId);
            Assert.AreNotEqual(hashedReport.LokationsId, saltedReport.LokationsId);

            Assert.IsTrue(Anonymizer.IsHashedKey(hashedReport.LokationsId));
            Assert.IsTrue(Anonymizer.IsHashedKey(saltedReport.LokationsId));
        }
Exemplo n.º 13
0
        public void GivenAnEmptyConfig_GenerateDefaultParametersIfNotConfigured_DefaultValueShouldBeAdded()
        {
            var configuration = new AnonymizerConfiguration();

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);

            configuration = new AnonymizerConfiguration()
            {
                ParameterConfiguration = new ParameterConfiguration()
            };
            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);
        }
        public AnonymizerConfigurationManager(AnonymizerConfiguration configuration)
        {
            _validator.Validate(configuration);
            configuration.GenerateDefaultParametersIfNotConfigured();

            _configuration = configuration;
            if (_configuration.PathRules != null)
            {
                _resourcePathRules = _configuration.PathRules.Where(entry => IsResourcePathRule(entry.Key))
                                     .GroupBy(entry => ExtractResourceTypeFromPath(entry.Key))
                                     .ToDictionary(group => group.Key, group => group.Select(item => new AnonymizerRule(item.Key, item.Value, AnonymizerRuleType.PathRule, item.Key)));
            }
            else
            {
                _resourcePathRules = new Dictionary <string, IEnumerable <AnonymizerRule> >();
            }
        }
Exemplo n.º 15
0
        public void GivenConfigWithParameter_GenerateDefaultParametersIfNotConfigured_ParametersShouldNotOverwrite()
        {
            var configuration = new AnonymizerConfiguration();

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);

            configuration = new AnonymizerConfiguration()
            {
                ParameterConfiguration = new ParameterConfiguration()
                {
                    DateShiftKey = "123"
                }
            };

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.Equal("123", configuration.ParameterConfiguration.DateShiftKey);
        }
        public void GivenAnEmptyConfig_GenerateDefaultParametersIfNotConfigured_DefaultValueShouldBeAdded()
        {
            var configuration = new AnonymizerConfiguration();

            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);
            Assert.Equal("http://127.0.0.1:5001", configuration.ParameterConfiguration.PresidioAnonymizerUrl);
            Assert.Equal("http://127.0.0.1:5002", configuration.ParameterConfiguration.PresidioAnalyzerUrl);
            Assert.Equal("en", configuration.ParameterConfiguration.PresidioAnalyzedLanguage);

            configuration = new AnonymizerConfiguration()
            {
                ParameterConfiguration = new ParameterConfiguration()
            };
            configuration.GenerateDefaultParametersIfNotConfigured();
            Assert.NotNull(configuration.ParameterConfiguration);
            Assert.Equal(32, configuration.ParameterConfiguration.DateShiftKey.Length);
        }
        public void GivenATypeRuleContainsAnother_WhenParseRule_NestedOneShouldOverwriteInheritedOne()
        {
            AnonymizerConfiguration configuration = new AnonymizerConfiguration()
            {
                PathRules = new Dictionary <string, string>(),
                ParameterConfiguration = new ParameterConfiguration(),
                TypeRules = new Dictionary <string, string>()
                {
                    { "Address", "redact" },
                    { "dateTime", "keep" }
                }
            };

            AnonymizerConfigurationManager configurationManager = new AnonymizerConfigurationManager(configuration);
            var context = ResourceAnonymizerContext.Create(TestPatientElementNode(), configurationManager);

            Assert.Contains("Patient.address", context.PathSet);
            Assert.Contains("Patient.address.period.start", context.PathSet);
            Assert.Equal("keep", context.RuleList.First(r => r.Path.Equals("Patient.address.period.start")).Method);
            Assert.Equal("redact", context.RuleList.First(r => r.Path.Equals("Patient.address")).Method);
        }
        public void GivenConflictTypeRuleAndPathRule_WhenParseRule_TypeRuleShouldBeIgnored()
        {
            AnonymizerConfiguration configuration = new AnonymizerConfiguration()
            {
                PathRules = new Dictionary <string, string>()
                {
                    { "Patient.address", "keep" }
                },
                ParameterConfiguration = new ParameterConfiguration(),
                TypeRules = new Dictionary <string, string>()
                {
                    { "Address", "redact" }
                }
            };

            AnonymizerConfigurationManager configurationManager = new AnonymizerConfigurationManager(configuration);
            var context = ResourceAnonymizerContext.Create(TestPatientElementNode(), configurationManager);

            Assert.Contains("Patient.address", context.PathSet);
            Assert.Equal("keep", context.RuleList.First().Method);
        }
Exemplo n.º 19
0
        public void TestSameHashDifferentObjectTypes()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            Energiemenge em = new Energiemenge()
            {
                LokationsId      = "DE0123456789012345678901234567890",
                LokationsTyp     = BO4E.ENUM.Lokationstyp.MeLo,
                Energieverbrauch = new List <Verbrauch>()
                {
                    new Verbrauch()
                    {
                        Wert = 123.456M,
                        Wertermittlungsverfahren = BO4E.ENUM.Wertermittlungsverfahren.MESSUNG,
                        Startdatum   = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc),
                        Enddatum     = new DateTime(2019, 2, 1, 0, 0, 0, DateTimeKind.Utc),
                        Obiskennzahl = "1-2-3-4",
                        Einheit      = BO4E.ENUM.Mengeneinheit.KWH
                    }
                }
            };

            Assert.IsTrue(em.IsValid());

            Messlokation melo = new Messlokation()
            {
                MesslokationsId = "DE0123456789012345678901234567890"
            };

            Assert.IsTrue(melo.IsValid());

            var conf = new AnonymizerConfiguration();

            conf.SetOption(DataCategory.POD, AnonymizerApproach.HASH);

            using Anonymizer anonymizer = new Anonymizer(conf);
            var hashedEm   = anonymizer.ApplyOperations <Energiemenge>(em);
            var hashedMelo = anonymizer.ApplyOperations <Messlokation>(melo);

            Assert.AreEqual(hashedEm.LokationsId, hashedMelo.MesslokationsId);
        }
Exemplo n.º 20
0
        public void GivenATypeRule_WhenParseRule_TransformedPathRuleShouldBeReturned()
        {
            AnonymizerConfiguration configuration = new AnonymizerConfiguration()
            {
                PathRules = new Dictionary <string, string>(),
                ParameterConfiguration = new ParameterConfiguration(),
                TypeRules = new Dictionary <string, string>()
                {
                    { "Address", "redact" },
                    { "HumanName", "redact" },
                    { "dateTime", "dateShift" }
                }
            };

            AnonymizerConfigurationManager configurationManager = new AnonymizerConfigurationManager(configuration);
            var context = ResourceAnonymizerContext.Create(TestPatientElementNode(), configurationManager);

            Assert.Contains("Patient.address", context.PathSet);
            Assert.Contains("Patient.name", context.PathSet);
            Assert.Contains("Patient.address.period.start", context.PathSet);
            Assert.Contains("Patient.identifier.period.start", context.PathSet);
        }
Exemplo n.º 21
0
        public void TestHashingDetectionForNonconformingString()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            Energiemenge em = new Energiemenge()
            {
                LokationsId      = "asdkasldkmaslkdmas", // not identifyable as lokationsId
                LokationsTyp     = BO4E.ENUM.Lokationstyp.MeLo,
                Energieverbrauch = new List <Verbrauch>()
            };

            Assert.IsFalse(Anonymizer.HasHashedKey(em));

            var hashConf = new AnonymizerConfiguration();

            hashConf.SetOption(DataCategory.POD, AnonymizerApproach.HASH);
            Energiemenge hashedEm;

            using (var a = new Anonymizer(hashConf))
            {
                hashedEm = a.ApplyOperations <Energiemenge>(em);
            }
            Assert.IsTrue(Anonymizer.HasHashedKey(hashedEm));
        }
        public AnonymizerConfigurationManager(AnonymizerConfiguration configuration)
        {
            EnsureArg.IsNotNull(configuration, nameof(configuration));

            Configuration = configuration;
        }
Exemplo n.º 23
0
        public void TestOperations()
        {
            BO4E.StaticLogger.Logger = new Microsoft.Extensions.Logging.Debug.DebugLogger("Testlogger", (log, level) => { return(true); });
            string[] files = Directory.GetFiles($"anonymizerTests/masterdata/", "*.json"); //
            foreach (string testFile in files)
            {
                JObject json;
                using (StreamReader r = new StreamReader(testFile))
                {
                    string jsonString = r.ReadToEnd();
                    json = JObject.Parse(jsonString);
                }

                BusinessObject bo;
                using (Anonymizer a = new Anonymizer(new AnonymizerConfiguration()))
                {
                    bo = JsonConvert.DeserializeObject <BusinessObject>(json["input"].ToString());
                    Assert.IsTrue(bo.Equals(a.ApplyOperations <BusinessObject>(bo)));
                }
                AnonymizerConfiguration      ac            = new AnonymizerConfiguration();
                HashSet <AnonymizerApproach> allApproaches = new HashSet <AnonymizerApproach>();;
                Dictionary <string, string>  operations    = JsonConvert.DeserializeObject <Dictionary <string, string> >(((JObject)json["operations"]).ToString());
                //Assert.AreEqual(json["input"].ToString(), resultJobject.ToString(), "Anonymizer without configuration should return the original message");
                foreach (string key in operations.Keys)
                {
                    Enum.TryParse(key, out DataCategory option);
                    Enum.TryParse(operations[key], out AnonymizerApproach approach);
                    Assert.IsNotNull(option, "Option invalid. Check test file " + testFile);
                    Assert.IsNotNull(approach, "Approach invalid, Check test file " + testFile);
                    ac.SetOption(option, approach);
                    allApproaches.Add(approach);
                }
                using (Anonymizer a = new Anonymizer(ac))
                {
                    if (ac.operations.ContainsValue(AnonymizerApproach.ENCRYPT))
                    {
                        X509Certificate2 x509certPubl = new X509Certificate2(X509Certificate2.CreateFromCertFile("anonymizerTests/certificates/publicX509Cert.crt"));
                        a.SetPublicKey(x509certPubl);
                    }
                    if (ac.operations.ContainsValue(AnonymizerApproach.HASH))
                    {
                        byte[] predefinedSalt = new byte[] { 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90 }; // only predefined for test case
                        a.SetHashingSalt(predefinedSalt);
                    }
                    JObject resultJobject = a.ApplyOperations <JObject>(JsonConvert.DeserializeObject <BusinessObject>(json["input"].ToString()));

                    if (allApproaches.Count == 1 && allApproaches.Contains(AnonymizerApproach.ENCRYPT))
                    {
                        // iff the file only contains encryption operations, we simple encrypt it once,
                        // decrypt the cipher text and assert they're equal. This complete reversion
                        // round trip is not possible if any other option like DELETE, REPLACE, HASH etc.
                        // is chosen.
                        AnonymizerConfiguration acInvert = new AnonymizerConfiguration();
                        foreach (string key in operations.Keys)
                        {
                            if (Enum.TryParse(operations[key], out AnonymizerApproach option))
                            {
                                if (Enum.TryParse(key, out DataCategory dc))
                                {
                                    acInvert.SetOption(dc, AnonymizerApproach.DECRYPT);
                                }
                            }
                        }
                        BusinessObject decryptedBo;
                        using (Anonymizer d = new Anonymizer(acInvert))
                        {
                            AsymmetricCipherKeyPair keyPair;
                            using (var reader = File.OpenText(@"anonymizerTests/certificates/privateKey.pem")) // file containing RSA PKCS1 private key
                            {
                                //Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters rpk = (Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters)new PemReader(reader).ReadObject();
                                keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject();
                            }
                            d.SetPrivateKey(keyPair.Private);
                            decryptedBo = d.ApplyOperations <BusinessObject>(resultJobject);
                        }
                        var    jdp = new JsonDiffPatch(); // https://github.com/wbish/jsondiffpatch.net
                        JToken left, right;
                        left  = JsonHelper.RemoveEmptyChildren(json["input"]);
                        right = JsonHelper.RemoveEmptyChildren(JObject.FromObject(decryptedBo));
                        var    patch             = jdp.Diff(left, right);
                        string additionalMessage = testFile;
                        if (patch != null)
                        {
                            additionalMessage = $";\r\n Diff: { patch.ToString()}";
                        }
                        // patch == null <--> jobjects match (except for key order)
                        Assert.IsNull(patch, $"Decryption failed: {testFile}{additionalMessage}");
                    }
                    else
                    {
                        //
                        // compare the processed result with a predefined json because the reversion
                        // round trip test is impossible
                        //
                        foreach (JProperty entry in json["assertions"])
                        {
                            string jsonpath       = entry.Name;
                            var    expectedResult = entry.Value;
                            JToken testResult     = resultJobject.SelectToken(jsonpath);
                            if (expectedResult != null && expectedResult.ToString() == "{}")
                            {
                                expectedResult = null;
                            }
                            if ((expectedResult == null || !expectedResult.HasValues) && testResult == null)
                            {
                                continue;
                            }
                            else if (expectedResult == null && testResult != null)
                            {
                                Assert.AreEqual(expectedResult, testResult.ToString(), $"Path {jsonpath} in {testFile} returned value {testResult} where null was expected.");
                            }
                            else if (expectedResult != null && testResult == null)
                            {
                                Assert.AreEqual(expectedResult.ToString(), testResult, $"Path {jsonpath} in {testFile} returned null where {expectedResult} was expected.");
                            }
                            else
                            {
                                Assert.AreEqual(expectedResult.ToString(), testResult.ToString(), $"Path {jsonpath} in {testFile} didn't return the expected result {expectedResult} but instead {testResult}");
                            }
                        }
                    }
                }
            }
        }