@@ -39,129 +39,121 @@ public class MigrationStep2
3939 {
4040 public static async Task < bool > MigrationStep2Example ( string kmsKeyId , string ddbTableName , string partitionKeyValue , string sortKeyWriteValue , string sortKeyReadValue )
4141 {
42- try
43- {
44- // 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
45- // For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
46- // We will use the `CreateMrkMultiKeyring` method to create this keyring,
47- // as it will correctly handle both single region and Multi-Region KMS Keys.
48- var matProv = new MaterialProviders ( new MaterialProvidersConfig ( ) ) ;
49- var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId } ;
50- var kmsKeyring = matProv . CreateAwsKmsMrkMultiKeyring ( keyringInput ) ;
51-
52- // 2. Configure which attributes are encrypted and/or signed when writing new items.
53- // For each attribute that may exist on the items we plan to write to our DynamoDbTable,
54- // we must explicitly configure how they should be treated during item encryption:
55- // - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
56- // - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
57- // - DO_NOTHING: The attribute is not encrypted and not included in the signature
58- var attributeActionsOnEncrypt = new Dictionary < string , CryptoAction >
59- {
60- [ "partition_key" ] = CryptoAction . SIGN_ONLY , // Our partition attribute must be SIGN_ONLY
61- [ "sort_key" ] = CryptoAction . SIGN_ONLY , // Our sort attribute must be SIGN_ONLY
62- [ "attribute1" ] = CryptoAction . ENCRYPT_AND_SIGN ,
63- [ "attribute2" ] = CryptoAction . SIGN_ONLY ,
64- [ "attribute3" ] = CryptoAction . DO_NOTHING
65- } ;
42+ // 1. Create a Keyring. This Keyring will be responsible for protecting the data keys that protect your data.
43+ // For this example, we will create a AWS KMS Keyring with the AWS KMS Key we want to use.
44+ // We will use the `CreateMrkMultiKeyring` method to create this keyring,
45+ // as it will correctly handle both single region and Multi-Region KMS Keys.
46+ var matProv = new MaterialProviders ( new MaterialProvidersConfig ( ) ) ;
47+ var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId } ;
48+ var kmsKeyring = matProv . CreateAwsKmsMrkMultiKeyring ( keyringInput ) ;
6649
67- // 3. Configure which attributes we expect to be excluded in the signature
68- // when reading items.
69- // For this example, we will explicitly list the attributes that are not signed.
70- var unsignedAttributes = new List < string > { "attribute3" } ;
50+ // 2. Configure which attributes are encrypted and/or signed when writing new items.
51+ // For each attribute that may exist on the items we plan to write to our DynamoDbTable,
52+ // we must explicitly configure how they should be treated during item encryption:
53+ // - ENCRYPT_AND_SIGN: The attribute is encrypted and included in the signature
54+ // - SIGN_ONLY: The attribute not encrypted, but is still included in the signature
55+ // - DO_NOTHING: The attribute is not encrypted and not included in the signature
56+ var attributeActionsOnEncrypt = new Dictionary < string , CryptoAction >
57+ {
58+ [ "partition_key" ] = CryptoAction . SIGN_ONLY , // Our partition attribute must be SIGN_ONLY
59+ [ "sort_key" ] = CryptoAction . SIGN_ONLY , // Our sort attribute must be SIGN_ONLY
60+ [ "attribute1" ] = CryptoAction . ENCRYPT_AND_SIGN ,
61+ [ "attribute2" ] = CryptoAction . SIGN_ONLY ,
62+ [ "attribute3" ] = CryptoAction . DO_NOTHING
63+ } ;
7164
72- // 4. Create the DynamoDb Encryption configuration for the table we will be writing to.
73- // This configuration uses PlaintextOverride.FORBID_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
74- // which means:
75- // - Write: Items are forbidden to be written as plaintext.
76- // Items will be written as encrypted items.
77- // - Read: Items are allowed to be read as plaintext.
78- // Items are allowed to be read as encrypted items.
79- var tableConfig = new DynamoDbTableEncryptionConfig
80- {
81- LogicalTableName = ddbTableName ,
82- PartitionKeyName = "partition_key" ,
83- SortKeyName = "sort_key" ,
84- AttributeActionsOnEncrypt = attributeActionsOnEncrypt ,
85- Keyring = kmsKeyring ,
86- AllowedUnsignedAttributes = unsignedAttributes ,
87- PlaintextOverride = PlaintextOverride . FORBID_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
88- } ;
65+ // 3. Configure which attributes we expect to be excluded in the signature
66+ // when reading items.
67+ // For this example, we will explicitly list the attributes that are not signed.
68+ var unsignedAttributes = new List < string > { "attribute3" } ;
8969
90- var tableConfigs = new Dictionary < string , DynamoDbTableEncryptionConfig >
91- {
92- [ ddbTableName ] = tableConfig
93- } ;
70+ // 4. Create the DynamoDb Encryption configuration for the table we will be writing to.
71+ // This configuration uses PlaintextOverride.FORBID_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
72+ // which means:
73+ // - Write: Items are forbidden to be written as plaintext.
74+ // Items will be written as encrypted items.
75+ // - Read: Items are allowed to be read as plaintext.
76+ // Items are allowed to be read as encrypted items.
77+ var tableConfig = new DynamoDbTableEncryptionConfig
78+ {
79+ LogicalTableName = ddbTableName ,
80+ PartitionKeyName = "partition_key" ,
81+ SortKeyName = "sort_key" ,
82+ AttributeActionsOnEncrypt = attributeActionsOnEncrypt ,
83+ Keyring = kmsKeyring ,
84+ AllowedUnsignedAttributes = unsignedAttributes ,
85+ PlaintextOverride = PlaintextOverride . FORBID_PLAINTEXT_WRITE_ALLOW_PLAINTEXT_READ
86+ } ;
9487
95- // 5. Create a new AWS SDK DynamoDb client using the TableEncryptionConfigs
96- var ddb = new Client . DynamoDbClient (
97- new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs } ) ;
88+ var tableConfigs = new Dictionary < string , DynamoDbTableEncryptionConfig >
89+ {
90+ [ ddbTableName ] = tableConfig
91+ } ;
9892
99- // 6. Put an item into our table using the above client.
100- // This item will be encrypted due to our PlaintextOverride configuration.
101- string encryptedAndSignedValue = MigrationUtils . ENCRYPTED_AND_SIGNED_VALUE ;
102- string signOnlyValue = MigrationUtils . SIGN_ONLY_VALUE ;
103- string doNothingValue = MigrationUtils . DO_NOTHING_VALUE ;
104- var item = new Dictionary < string , AttributeValue >
105- {
106- [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
107- [ "sort_key" ] = new AttributeValue { N = sortKeyWriteValue } ,
108- [ "attribute1" ] = new AttributeValue { S = encryptedAndSignedValue } ,
109- [ "attribute2" ] = new AttributeValue { S = signOnlyValue } ,
110- [ "attribute3" ] = new AttributeValue { S = doNothingValue }
111- } ;
93+ // 5. Create a new AWS SDK DynamoDb client using the TableEncryptionConfigs
94+ var ddb = new Client . DynamoDbClient (
95+ new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs } ) ;
11296
113- var putRequest = new PutItemRequest
114- {
115- TableName = ddbTableName ,
116- Item = item
117- } ;
97+ // 6. Put an item into our table using the above client.
98+ // This item will be encrypted due to our PlaintextOverride configuration.
99+ string encryptedAndSignedValue = MigrationUtils . ENCRYPTED_AND_SIGNED_VALUE ;
100+ string signOnlyValue = MigrationUtils . SIGN_ONLY_VALUE ;
101+ string doNothingValue = MigrationUtils . DO_NOTHING_VALUE ;
102+ var item = new Dictionary < string , AttributeValue >
103+ {
104+ [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
105+ [ "sort_key" ] = new AttributeValue { N = sortKeyWriteValue } ,
106+ [ "attribute1" ] = new AttributeValue { S = encryptedAndSignedValue } ,
107+ [ "attribute2" ] = new AttributeValue { S = signOnlyValue } ,
108+ [ "attribute3" ] = new AttributeValue { S = doNothingValue }
109+ } ;
118110
119- var putResponse = await ddb . PutItemAsync ( putRequest ) ;
120- Debug . Assert ( putResponse . HttpStatusCode == HttpStatusCode . OK ) ;
111+ var putRequest = new PutItemRequest
112+ {
113+ TableName = ddbTableName ,
114+ Item = item
115+ } ;
121116
122- // 7. Get an item back from the table using the same client.
123- // If this is an item written in plaintext (i.e. any item written
124- // during Step 0 or 1), then the item will still be in plaintext.
125- // If this is an item that was encrypted client-side (i.e. any item written
126- // during Step 2 or after), then the item will be decrypted client-side
127- // and surfaced as a plaintext item.
128- var key = new Dictionary < string , AttributeValue >
129- {
130- [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
131- [ "sort_key" ] = new AttributeValue { N = sortKeyReadValue }
132- } ;
117+ var putResponse = await ddb . PutItemAsync ( putRequest ) ;
118+ Debug . Assert ( putResponse . HttpStatusCode == HttpStatusCode . OK ) ;
133119
134- var getRequest = new GetItemRequest
135- {
136- TableName = ddbTableName ,
137- Key = key ,
138- // In this example we configure a strongly consistent read
139- // because we perform a read immediately after a write (for demonstrative purposes).
140- // By default, reads are only eventually consistent.
141- ConsistentRead = true
142- } ;
120+ // 7. Get an item back from the table using the same client.
121+ // If this is an item written in plaintext (i.e. any item written
122+ // during Step 0 or 1), then the item will still be in plaintext.
123+ // If this is an item that was encrypted client-side (i.e. any item written
124+ // during Step 2 or after), then the item will be decrypted client-side
125+ // and surfaced as a plaintext item.
126+ var key = new Dictionary < string , AttributeValue >
127+ {
128+ [ "partition_key" ] = new AttributeValue { S = partitionKeyValue } ,
129+ [ "sort_key" ] = new AttributeValue { N = sortKeyReadValue }
130+ } ;
143131
144- var getResponse = await ddb . GetItemAsync ( getRequest ) ;
145- Debug . Assert ( getResponse . HttpStatusCode == HttpStatusCode . OK ) ;
132+ var getRequest = new GetItemRequest
133+ {
134+ TableName = ddbTableName ,
135+ Key = key ,
136+ // In this example we configure a strongly consistent read
137+ // because we perform a read immediately after a write (for demonstrative purposes).
138+ // By default, reads are only eventually consistent.
139+ ConsistentRead = true
140+ } ;
146141
147- // 8. Verify we get the expected item back
148- if ( getResponse . Item == null )
149- {
150- throw new Exception ( "No item found" ) ;
151- }
142+ var getResponse = await ddb . GetItemAsync ( getRequest ) ;
143+ Debug . Assert ( getResponse . HttpStatusCode == HttpStatusCode . OK ) ;
152144
153- bool success = MigrationUtils . VerifyReturnedItem ( getResponse , partitionKeyValue , sortKeyReadValue ) ;
154- if ( success )
155- {
156- Console . WriteLine ( "MigrationStep2 completed successfully" ) ;
157- }
158- return success ;
145+ // 8. Verify we get the expected item back
146+ if ( getResponse . Item == null )
147+ {
148+ throw new Exception ( "No item found" ) ;
159149 }
160- catch ( Exception e )
150+
151+ bool success = MigrationUtils . VerifyReturnedItem ( getResponse , partitionKeyValue , sortKeyReadValue ) ;
152+ if ( success )
161153 {
162- Console . WriteLine ( $ "Error in MigrationStep2: { e . Message } ") ;
163- throw ;
154+ Console . WriteLine ( "MigrationStep2 completed successfully" ) ;
164155 }
156+ return success ;
165157 }
166158 }
167159}
0 commit comments