private void TestFullBuilderPath() { BasicExpiringCryptoPolicy.IKeyExpirationDaysStep builder = BasicExpiringCryptoPolicy.NewBuilder(); BasicExpiringCryptoPolicy basicExpiringCryptoPolicy = builder .WithKeyExpirationDays(TestExpirationDays) .WithRevokeCheckMinutes(TestCachingPeriod) .WithRotationStrategy(CryptoPolicy.KeyRotationStrategy.Queued) .WithCanCacheSystemKeys(false) .WithCanCacheIntermediateKeys(false) .WithCanCacheSessions(true) .WithSessionCacheMaxSize(42) .WithSessionCacheExpireMillis(33000) .WithNotifyExpiredSystemKeyOnRead(true) .WithNotifyExpiredIntermediateKeyOnRead(true) .Build(); Assert.NotNull(basicExpiringCryptoPolicy); Assert.Equal(CryptoPolicy.KeyRotationStrategy.Queued, basicExpiringCryptoPolicy.GetKeyRotationStrategy()); Assert.False(basicExpiringCryptoPolicy.CanCacheSystemKeys()); Assert.False(basicExpiringCryptoPolicy.CanCacheIntermediateKeys()); Assert.True(basicExpiringCryptoPolicy.CanCacheSessions()); Assert.Equal(42, basicExpiringCryptoPolicy.GetSessionCacheMaxSize()); Assert.Equal(33000, basicExpiringCryptoPolicy.GetSessionCacheExpireMillis()); Assert.True(basicExpiringCryptoPolicy.NotifyExpiredSystemKeyOnRead()); Assert.True(basicExpiringCryptoPolicy.NotifyExpiredIntermediateKeyOnRead()); }
private void TestSessionCacheSetupAndDispose() { // Test flows around session cache setup, including cache loader and removal flows (via dispose) CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .Build(); MemoryCache sessionCache; using (SessionFactory factory = new SessionFactory( TestProductId, TestServiceId, metastoreMock.Object, systemKeyCacheMock.Object, policy, keyManagementServiceMock.Object)) { sessionCache = factory.SessionCache; using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes("1234")) { Assert.NotNull(sessionBytes); } // Verify nothing evicted yet Assert.True(sessionCache.Count > 0); } // Verify closing the factory invalidated and cleaned up entries Assert.True(sessionCache.Count == 0); }
static CustomerController() { long sessionCacheSize; if (!long.TryParse(Environment.GetEnvironmentVariable("ASHERAH_SESSION_CACHE_SIZE"), out sessionCacheSize)) { sessionCacheSize = 100; } CryptoPolicy cryptoPolicy = BasicExpiringCryptoPolicy .NewBuilder() .WithKeyExpirationDays(30) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) // Enable session cache .WithSessionCacheMaxSize(sessionCacheSize) // Define the number of maximum sessions to cache .WithSessionCacheExpireMillis(5000) // Evict the session from cache after some milliseconds .Build(); _sessionFactory = SessionFactory .NewBuilder("myapp", "api") .WithInMemoryMetastore() .WithCryptoPolicy(cryptoPolicy) .WithStaticKeyManagementService("thisIsAStaticMasterKeyForTesting") .Build(); }
public void IDecryptTheEncrypted_Data() { KeyManagementService keyManagementService = new StaticKeyManagementServiceImpl(KeyManagementStaticMasterKey); AdoMetastoreImpl metastore = AdoMetastoreImpl .NewBuilder(MySqlClientFactory.Instance, AdoConnectionString) .Build(); CryptoPolicy cryptoPolicy = BasicExpiringCryptoPolicy .NewBuilder() .WithKeyExpirationDays(KeyExpiryDays) .WithRevokeCheckMinutes(RevokeCheckMinutes) .Build(); // Create a session factory for the test using (SessionFactory sessionFactory = SessionFactory .NewBuilder(DefaultProductId, DefaultServiceId) .WithMetastore(metastore) .WithCryptoPolicy(cryptoPolicy) .WithKeyManagementService(keyManagementService) .Build()) { // Now create an actual session for a partition (which in our case is a dummy id). This session is used // for a transaction and is disposed automatically after use due to the IDisposable implementation. using (Session <byte[], byte[]> sessionBytes = sessionFactory.GetSessionBytes(DefaultPartitionId)) { decryptedPayload = Encoding.UTF8.GetString(sessionBytes.Decrypt(encryptedPayload)); } } }
private void TestSessionCacheGetSessionWithMaxSessionNotReachedShouldNotEvict() { long sessionCacheMaxSize = 2; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .WithSessionCacheMaxSize(sessionCacheMaxSize) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = null; using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); } using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId + 1)) { } // Sleep to attempt to trigger eviction on next access if it were going to try { Thread.Sleep(100); } catch (Exception e) { Assert.True(false, e.Message); } // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // Try to use same partition to get the same cached session while it's still in use using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); // we should not hit the metastore since the session should not have been evicted metastoreSpy.Verify( x => x.Load(It.IsAny <string>(), It.IsAny <DateTimeOffset>()), Times.Never); } } }
private void TestPrimaryBuilderPath() { BasicExpiringCryptoPolicy.IKeyExpirationDaysStep builder = BasicExpiringCryptoPolicy.NewBuilder(); BasicExpiringCryptoPolicy basicExpiringCryptoPolicy = builder. WithKeyExpirationDays(TestExpirationDays). WithRevokeCheckMinutes(TestCachingPeriod).Build(); Assert.NotNull(basicExpiringCryptoPolicy); }
private void TestSessionCacheGetSessionWithMaxSessionReachedShouldEvict() { long sessionCacheMaxSize = 2; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .WithSessionCacheMaxSize(sessionCacheMaxSize) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = null; Partition partition = factory.GetPartition(TestPartitionId); using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); } // Try to create more sessions to exceed the max size using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId + 1)) { } using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId + 2)) { } // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // Try to use same partition to get the same session we might have cached earlier using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); // we should hit the metastore since the session should have been evicted as the size limit was reached metastoreSpy.Verify( x => x.Load(It.IsAny <string>(), It.IsAny <DateTimeOffset>())); } } }
private void TestSessionCacheGetSessionAfterUseAndExpiredShouldEvict() { long sessionCacheExpireMillis = 10; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithSessionCacheExpireMillis(sessionCacheExpireMillis) .WithCanCacheSessions(true) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = null; Partition partition = factory.GetPartition(TestPartitionId); using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); } // Sleep to trigger the expiration try { Thread.Sleep((int)sessionCacheExpireMillis * 3); } catch (Exception e) { Assert.True(false, e.Message); } // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // This will actually create a new session and the previous one will be removed/closed due to expiry using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); // metastore should have an interaction in the decrypt flow since the cached session expired metastoreSpy.Verify( x => x.Load(partition.IntermediateKeyId, It.IsAny <DateTimeOffset>())); } } }
private void TestSessionCacheGetSessionWhileStillUsedAndExpiredShouldNotEvict() { long sessionCacheExpireMillis = 30; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .WithSessionCacheExpireMillis(sessionCacheExpireMillis) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = sessionBytes.Encrypt(payload); // Sleep to trigger the expiration try { Thread.Sleep((int)sessionCacheExpireMillis * 3); } catch (Exception e) { Assert.True(false, e.Message); } // Even after timeout, verify that we have one entry in cache Assert.Equal(1, factory.SessionCache.Count); // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // Use same partition to get the same cached (but expired) session while it's still in use using (Session <byte[], byte[]> session2 = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayload = session2.Decrypt(drr); Assert.Equal(payload, decryptedPayload); // verify no metastore interactions in the decrypt flow (since IKs cached via session caching) metastoreSpy.Verify( x => x.Load(It.IsAny <string>(), It.IsAny <DateTimeOffset>()), Times.Never); } } } }
private static object[] GenerateMocks(KeyState cacheIK, KeyState metaIK, KeyState cacheSK, KeyState metaSK) { AppEncryptionPartition appEncryptionPartition = new AppEncryptionPartition( cacheIK + "CacheIK_" + metaIK + "MetaIK_" + DateTimeUtils.GetCurrentTimeAsUtcIsoDateTimeOffset() + "_" + Random.Next(), cacheSK + "CacheSK_" + metaSK + "MetaSK_" + DateTimeUtils.GetCurrentTimeAsUtcIsoDateTimeOffset() + "_" + Random.Next(), DefaultProductId); // TODO Update to create KeyManagementService based on config/param once we plug in AWS KMS KeyManagementService kms = new StaticKeyManagementServiceImpl(KeyManagementStaticMasterKey); CryptoKeyHolder cryptoKeyHolder = CryptoKeyHolder.GenerateIKSK(); // TODO Pass Metastore type to enable spy generation once we plug in external metastore types Mock <MemoryPersistenceImpl <JObject> > metastorePersistence = MetastoreMock.CreateMetastoreMock(appEncryptionPartition, kms, metaIK, metaSK, cryptoKeyHolder); CacheMock cacheMock = CacheMock.CreateCacheMock(cacheIK, cacheSK, cryptoKeyHolder); // Mimics (mostly) the old TimeBasedCryptoPolicyImpl settings CryptoPolicy cryptoPolicy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(KeyExpiryDays) .WithRevokeCheckMinutes(int.MaxValue) .WithCanCacheIntermediateKeys(false) .WithCanCacheSystemKeys(false) .Build(); SecureCryptoKeyDictionary <DateTimeOffset> intermediateKeyCache = cacheMock.IntermediateKeyCache; SecureCryptoKeyDictionary <DateTimeOffset> systemKeyCache = cacheMock.SystemKeyCache; EnvelopeEncryptionJsonImpl envelopeEncryptionJson = new EnvelopeEncryptionJsonImpl( appEncryptionPartition, metastorePersistence.Object, systemKeyCache, new FakeSecureCryptoKeyDictionaryFactory <DateTimeOffset>(intermediateKeyCache), new BouncyAes256GcmCrypto(), cryptoPolicy, kms); IEnvelopeEncryption <byte[]> envelopeEncryptionByteImpl = new EnvelopeEncryptionBytesImpl(envelopeEncryptionJson); // Need to manually set a no-op metrics instance IMetrics metrics = new MetricsBuilder() .Configuration.Configure(options => options.Enabled = false) .Build(); MetricsUtil.SetMetricsInstance(metrics); return(new object[] { envelopeEncryptionByteImpl, metastorePersistence, cacheIK, metaIK, cacheSK, metaSK, appEncryptionPartition }); }
private void TestSessionCacheMultiThreadedWithExpirationDifferentSessions() { long sessionCacheExpireMillis = 10; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithSessionCacheExpireMillis(sessionCacheExpireMillis) .WithCanCacheSessions(true) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { int numThreads = 100; int numRequests = 100; // Get the current settings and try to force minWorkers ThreadPool.GetMinThreads(out _, out var currentMinIOC); Assert.True(ThreadPool.SetMinThreads(numThreads, currentMinIOC)); long completedTasks = 0; Parallel.ForEach(Enumerable.Range(0, numRequests), i => { using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId + i)) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); Interlocked.Increment(ref completedTasks); // Sleep to trigger expiration Thread.Sleep((int)sessionCacheExpireMillis * 3); } }); // Wait for all threads to complete Assert.Equal(numRequests, completedTasks); // Verify that number of entries in cache equal number of partitions Assert.Equal(numRequests, factory.SessionCache.Count); } }
private void TestSessionCacheGetSessionWithMaxSessionReachedButStillUsedShouldNotEvict() { long sessionCacheMaxSize = 1; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .WithSessionCacheMaxSize(sessionCacheMaxSize) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = sessionBytes.Encrypt(payload); // Force us to hit the max cache size using (Session <byte[], byte[]> session2 = factory.GetSessionBytes(TestPartitionId + 1)) { byte[] drr1 = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr1); Assert.Equal(payload, decryptedPayload); // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // Get same session as the outer-most block since this should force both of the sessions to stay using (Session <byte[], byte[]> sessionBytesDup = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayloadDup = sessionBytesDup.Decrypt(drr); Assert.Equal(payload, decryptedPayloadDup); // we should not hit the metastore since the session should not have been evicted metastoreSpy.Verify( x => x.Load(It.IsAny <string>(), It.IsAny <DateTimeOffset>()), Times.Never); } } } } }
private void TestSessionCacheGetSessionAfterUseAndNotExpiredShouldNotEvict() { CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithMetastore(metastoreSpy.Object) .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = null; using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); } // Note we do not sleep // Reset so we can examine 2nd session's interactions metastoreSpy.Reset(); // Use same partition to get the same cached session while it's still in use using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); // verify no metastore interactions in the decrypt flow (since IKs cached via session caching) metastoreSpy.Verify( x => x.Load(It.IsAny <string>(), It.IsAny <DateTimeOffset>()), Times.Never); } // Verify that nothing is evicted from cache since the session is still in use. Assert.Equal(1, factory.SessionCache.Count); } }
private object[] GenerateMocks(KeyState cacheIK, KeyState metaIK, KeyState cacheSK, KeyState metaSK) { Partition partition = new Partition( cacheIK + "CacheIK_" + metaIK + "MetaIK_" + DateTimeUtils.GetCurrentTimeAsUtcIsoDateTimeOffset() + "_" + Random.Next(), cacheSK + "CacheSK_" + metaSK + "MetaSK_" + DateTimeUtils.GetCurrentTimeAsUtcIsoDateTimeOffset() + "_" + Random.Next(), DefaultProductId); KeyManagementService kms = configFixture.KeyManagementService; CryptoKeyHolder cryptoKeyHolder = CryptoKeyHolder.GenerateIKSK(); Mock <IMetastore <JObject> > metastoreMock = MetastoreMock.CreateMetastoreMock( partition, kms, metaIK, metaSK, cryptoKeyHolder, configFixture.Metastore); CacheMock cacheMock = CacheMock.CreateCacheMock(cacheIK, cacheSK, cryptoKeyHolder); // Mimics (mostly) the old TimeBasedCryptoPolicyImpl settings CryptoPolicy cryptoPolicy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(KeyExpiryDays) .WithRevokeCheckMinutes(int.MaxValue) .WithCanCacheIntermediateKeys(false) .WithCanCacheSystemKeys(false) .Build(); SecureCryptoKeyDictionary <DateTimeOffset> intermediateKeyCache = cacheMock.IntermediateKeyCache; SecureCryptoKeyDictionary <DateTimeOffset> systemKeyCache = cacheMock.SystemKeyCache; EnvelopeEncryptionJsonImpl envelopeEncryptionJson = new EnvelopeEncryptionJsonImpl( partition, metastoreMock.Object, systemKeyCache, new FakeSecureCryptoKeyDictionaryFactory <DateTimeOffset>(intermediateKeyCache), new BouncyAes256GcmCrypto(), cryptoPolicy, kms); IEnvelopeEncryption <byte[]> envelopeEncryptionByteImpl = new EnvelopeEncryptionBytesImpl(envelopeEncryptionJson); return(new object[] { envelopeEncryptionByteImpl, metastoreMock, cacheIK, metaIK, cacheSK, metaSK, partition }); }
private void TestSessionCacheMultiThreadedWithMaxSessionReachedSameSession() { long sessionCacheMaxSize = 1; CryptoPolicy policy = BasicExpiringCryptoPolicy.NewBuilder() .WithKeyExpirationDays(1) .WithRevokeCheckMinutes(30) .WithCanCacheSessions(true) .WithSessionCacheMaxSize(sessionCacheMaxSize) .Build(); using (SessionFactory factory = SessionFactory.NewBuilder(TestProductId, TestServiceId) .WithInMemoryMetastore() .WithCryptoPolicy(policy) .WithStaticKeyManagementService(TestStaticMasterKey) .Build()) { int numThreads = 100; int numRequests = 100; // Get the current settings and try to force minWorkers ThreadPool.GetMinThreads(out _, out var currentMinIOC); Assert.True(ThreadPool.SetMinThreads(numThreads, currentMinIOC)); long completedTasks = 0; Parallel.ForEach(Enumerable.Range(0, numRequests), i => { using (Session <byte[], byte[]> sessionBytes = factory.GetSessionBytes(TestPartitionId)) { byte[] payload = { 0, 1, 2, 3, 4, 5, 6, 7 }; byte[] drr = sessionBytes.Encrypt(payload); byte[] decryptedPayload = sessionBytes.Decrypt(drr); Assert.Equal(payload, decryptedPayload); Interlocked.Increment(ref completedTasks); } }); // Wait for all threads to complete Assert.Equal(numRequests, completedTasks); Assert.Equal(1, factory.SessionCache.Count); } }
private static async void App(Options options) { IMetastore <JObject> metastore = null; KeyManagementService keyManagementService = null; if (options.Metastore == Metastore.ADO) { if (options.AdoConnectionString != null) { logger.LogInformation("using ADO-based metastore..."); metastore = AdoMetastoreImpl .NewBuilder(MySqlClientFactory.Instance, options.AdoConnectionString) .Build(); } else { logger.LogError("ADO connection string is a mandatory parameter with Metastore Type: ADO"); Console.WriteLine(HelpText.AutoBuild(cmdOptions, null, null)); return; } } else if (options.Metastore == Metastore.DYNAMODB) { logger.LogInformation("using DynamoDB-based metastore..."); AWSConfigs.AWSRegion = "us-west-2"; metastore = DynamoDbMetastoreImpl.NewBuilder().Build(); } else { logger.LogInformation("using in-memory metastore..."); metastore = new InMemoryMetastoreImpl <JObject>(); } if (options.Kms == Kms.AWS) { if (options.PreferredRegion != null && options.RegionToArnTuples != null) { Dictionary <string, string> regionToArnDictionary = new Dictionary <string, string>(); foreach (string regionArnPair in options.RegionToArnTuples) { string[] regionArnArray = regionArnPair.Split("="); regionToArnDictionary.Add(regionArnArray[0], regionArnArray[1]); } logger.LogInformation("using AWS KMS..."); keyManagementService = AwsKeyManagementServiceImpl .NewBuilder(regionToArnDictionary, options.PreferredRegion).Build(); } else { logger.LogError("Preferred region and <region>=<arn> tuples are mandatory with KMS Type: AWS"); Console.WriteLine(HelpText.AutoBuild(cmdOptions, null, null)); return; } } else { logger.LogInformation("using static KMS..."); keyManagementService = new StaticKeyManagementServiceImpl("mysupersecretstaticmasterkey!!!!"); } CryptoPolicy cryptoPolicy = BasicExpiringCryptoPolicy .NewBuilder() .WithKeyExpirationDays(KeyExpirationDays) .WithRevokeCheckMinutes(CacheCheckMinutes) .Build(); // Setup metrics reporters and always include console. IMetricsBuilder metricsBuilder = new MetricsBuilder() .Report.ToConsole(consoleOptions => consoleOptions.FlushInterval = TimeSpan.FromSeconds(60)); // CloudWatch metrics generation if (options.EnableCloudWatch) { // Fill in when we open source our App.Metrics cloudwatch reporter separately } IMetrics metrics = metricsBuilder.Build(); // Create a session factory for this app. Normally this would be done upon app startup and the // same factory would be used anytime a new session is needed for a partition (e.g., shopper). // We've split it out into multiple using blocks to underscore this point. using (SessionFactory sessionFactory = SessionFactory .NewBuilder("productId", "reference_app") .WithMetastore(metastore) .WithCryptoPolicy(cryptoPolicy) .WithKeyManagementService(keyManagementService) .WithMetrics(metrics) .Build()) { // Now create an actual session for a partition (which in our case is a pretend shopper id). This session is used // for a transaction and is disposed automatically after use due to the IDisposable implementation. using (Session <byte[], byte[]> sessionBytes = sessionFactory.GetSessionBytes("shopper123")) { const string originalPayloadString = "mysupersecretpayload"; foreach (int i in Enumerable.Range(0, options.Iterations)) { string dataRowString; // If we get a DRR as a command line argument, we want to directly decrypt it if (options.Drr != null) { dataRowString = options.Drr; } else { // Encrypt the payload byte[] dataRowRecordBytes = sessionBytes.Encrypt(Encoding.UTF8.GetBytes(originalPayloadString)); // Consider this us "persisting" the DRR dataRowString = Convert.ToBase64String(dataRowRecordBytes); } logger.LogInformation("dataRowRecord as string = {dataRow}", dataRowString); byte[] newDataRowRecordBytes = Convert.FromBase64String(dataRowString); // Decrypt the payload string decryptedPayloadString = Encoding.UTF8.GetString(sessionBytes.Decrypt(newDataRowRecordBytes)); logger.LogInformation("decryptedPayloadString = {payload}", decryptedPayloadString); logger.LogInformation("matches = {result}", originalPayloadString.Equals(decryptedPayloadString)); } } } // Force final publish of metrics await Task.WhenAll(((IMetricsRoot)metrics).ReportRunner.RunAllAsync()); }