1010import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBRangeKey ;
1111import com .amazonaws .services .dynamodbv2 .datamodeling .DynamoDBTable ;
1212import com .amazonaws .services .dynamodbv2 .datamodeling .encryption .DynamoDBEncryptor ;
13+ import com .amazonaws .services .dynamodbv2 .datamodeling .encryption .EncryptionContext ;
14+ import com .amazonaws .services .dynamodbv2 .datamodeling .encryption .EncryptionFlags ;
1315import com .amazonaws .services .dynamodbv2 .datamodeling .encryption .providers .DirectKmsMaterialProvider ;
1416import com .amazonaws .services .dynamodbv2 .model .AttributeValue ;
1517import com .amazonaws .services .kms .AWSKMS ;
1618import com .amazonaws .services .kms .AWSKMSClientBuilder ;
1719
1820import java .security .GeneralSecurityException ;
21+ import java .util .EnumSet ;
1922import java .util .HashMap ;
2023import java .util .Map ;
24+ import java .util .Set ;
2125
2226import static com .amazonaws .services .dynamodbv2 .datamodeling .encryption .utils .EncryptionContextOperators .overrideEncryptionContextTableNameUsingMap ;
2327
@@ -27,30 +31,41 @@ public static void main(String[] args) throws GeneralSecurityException {
2731 final String region = args [1 ];
2832 final String encryptionContextTableName = args [2 ];
2933
30- encryptRecord (cmkArn , region , encryptionContextTableName );
34+ AmazonDynamoDB ddb = null ;
35+ AWSKMS kms = null ;
36+ try {
37+ ddb = AmazonDynamoDBClientBuilder .standard ().withRegion (region ).build ();
38+ kms = AWSKMSClientBuilder .standard ().withRegion (region ).build ();
39+ encryptRecord (cmkArn , encryptionContextTableName , ddb , kms );
40+ } finally {
41+ if (ddb != null ) {
42+ ddb .shutdown ();
43+ }
44+ if (kms != null ) {
45+ kms .shutdown ();
46+ }
47+ }
3148 }
3249
3350 public static void encryptRecord (final String cmkArn ,
34- final String region ,
35- final String newEncryptionContextTableName ) {
51+ final String newEncryptionContextTableName ,
52+ AmazonDynamoDB ddb ,
53+ AWSKMS kms ) throws GeneralSecurityException {
3654 // Sample object to be encrypted
3755 ExampleItem record = new ExampleItem ();
3856 record .setPartitionAttribute ("is this" );
3957 record .setSortAttribute (55 );
4058 record .setExample ("my data" );
4159
4260 // Set up our configuration and clients
43- final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder .standard ().withRegion (region ).build ();
44- final AWSKMS kms = AWSKMSClientBuilder .standard ().withRegion (region ).build ();
4561 final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider (kms , cmkArn );
46- // Encryptor creation
4762 final DynamoDBEncryptor encryptor = DynamoDBEncryptor .getInstance (cmp );
4863
4964 Map <String , String > tableNameEncryptionContextOverrides = new HashMap <>();
5065 tableNameEncryptionContextOverrides .put ("ExampleTableForEncryptionContextOverrides" , newEncryptionContextTableName );
5166 tableNameEncryptionContextOverrides .put ("AnotherExampleTableForEncryptionContextOverrides" , "this table doesn't exist" );
5267
53- // Here we supply an operator to override the table name used in the encryption context
68+ // Supply an operator to override the table name used in the encryption context
5469 encryptor .setEncryptionContextOverrideOperator (
5570 overrideEncryptionContextTableNameUsingMap (tableNameEncryptionContextOverrides )
5671 );
@@ -62,20 +77,40 @@ public static void encryptRecord(final String cmkArn,
6277 .withSaveBehavior (DynamoDBMapperConfig .SaveBehavior .CLOBBER ).build ();
6378 DynamoDBMapper mapper = new DynamoDBMapper (ddb , mapperConfig , new AttributeEncryptor (encryptor ));
6479
65- System .out .println ("Plaintext Record: " + record );
80+ System .out .println ("Plaintext Record: " + record . toString () );
6681 // Save the record to the DynamoDB table
6782 mapper .save (record );
6883
69- // Retrieve the encrypted record (directly without decrypting) from Dynamo so we can see it in our example
84+ // Retrieve (and decrypt) it from DynamoDB
85+ ExampleItem decrypted_record = mapper .load (ExampleItem .class , "is this" , 55 );
86+ System .out .println ("Decrypted Record: " + decrypted_record .toString ());
87+
88+ // Setup new configuration to decrypt without using an overridden EncryptionContext
7089 final Map <String , AttributeValue > itemKey = new HashMap <>();
7190 itemKey .put ("partition_attribute" , new AttributeValue ().withS ("is this" ));
7291 itemKey .put ("sort_attribute" , new AttributeValue ().withN ("55" ));
73- System .out .println ("Encrypted Record: " + ddb .getItem ("ExampleTableForEncryptionContextOverrides" ,
74- itemKey ).getItem ());
7592
76- // Retrieve (and decrypt) it from DynamoDB
77- ExampleItem decrypted_record = mapper .load (ExampleItem .class , "is this" , 55 );
78- System .out .println ("Decrypted Record: " + decrypted_record );
93+ final EnumSet <EncryptionFlags > signOnly = EnumSet .of (EncryptionFlags .SIGN );
94+ final EnumSet <EncryptionFlags > encryptAndSign = EnumSet .of (EncryptionFlags .ENCRYPT , EncryptionFlags .SIGN );
95+ final Map <String , AttributeValue > encryptedItem = ddb .getItem ("ExampleTableForEncryptionContextOverrides" , itemKey )
96+ .getItem ();
97+ System .out .println ("Encrypted Record: " + encryptedItem );
98+
99+ Map <String , Set <EncryptionFlags >> encryptionFlags = new HashMap <>();
100+ encryptionFlags .put ("partition_attribute" , signOnly );
101+ encryptionFlags .put ("sort_attribute" , signOnly );
102+ encryptionFlags .put ("example" , encryptAndSign );
103+
104+ final DynamoDBEncryptor encryptorWithoutOverrides = DynamoDBEncryptor .getInstance (cmp );
105+
106+ // Decrypt the record without using an overridden EncryptionContext
107+ encryptorWithoutOverrides .decryptRecord (encryptedItem ,
108+ encryptionFlags ,
109+ new EncryptionContext .Builder ().withHashKeyName ("partition_attribute" )
110+ .withRangeKeyName ("sort_attribute" )
111+ .withTableName (newEncryptionContextTableName )
112+ .build ());
113+ System .out .printf ("The example item was encrypted using the table name '%s' in the EncryptionContext%n" , newEncryptionContextTableName );
79114 }
80115
81116 @ DynamoDBTable (tableName = "ExampleTableForEncryptionContextOverrides" )
@@ -110,6 +145,11 @@ public String getExample() {
110145 public void setExample (String example ) {
111146 this .example = example ;
112147 }
148+
149+ public String toString () {
150+ return String .format ("{partition_attribute: %s, sort_attribute: %s, example: %s}" ,
151+ partitionAttribute , sortAttribute , example );
152+ }
113153 }
114154
115155}
0 commit comments