Java examples
Our client-side encryption library was renamed to the AWS Database Encryption SDK. This developer guide still provides information on the DynamoDB Encryption Client. |
The following examples show you how to use the Java client-side encryption library for DynamoDB to protect the table items in
your application. You can find more examples (and contribute your own) in the Java examples
The following examples demonstrate how to configure the Java client-side encryption library for DynamoDB in a new, unpopulated Amazon DynamoDB table. If you want to configure your existing Amazon DynamoDB tables for client-side encryption, see Add version 3.x to an existing table.
Topics
Using the DynamoDB enhanced client
The following example shows how to use the DynamoDB Enhanced Client and
DynamoDbEncryptionInterceptor
with an AWS KMS keyring to encrypt DynamoDB table items as part of your DynamoDB API
calls.
You can use any supported keyring with the DynamoDB Enhanced Client, but we recommend using one of the AWS KMS keyrings whenever possible.
Note
The DynamoDB Enhanced Client does not support searchable encryption. Use the
DynamoDbEncryptionInterceptor
with the low-level DynamoDB API to use
searchable encryption.
See the complete code sample: EnhancedPutGetExample.java
- Step 1: Create the AWS KMS keyring
-
The following example uses
CreateAwsKmsMrkMultiKeyring
to create an AWS KMS keyring with a symmetric encryption KMS key. TheCreateAwsKmsMrkMultiKeyring
method ensures that the keyring will correctly handle both single-Region and multi-Region keys.final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(kmsKeyId) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
- Step 2: Create a table schema from the annotated data class
-
The following example uses the annotated data class to create the
TableSchema
.This example assumes that the annotated data class and attribute actions were defined using the SimpleClass.java
. For more guidance on annotating your attribute actions, see Use an annotated data class. Note
The AWS Database Encryption SDK does not support annotations on nested attributes.
final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);
- Step 3: Define which attributes are excluded from the signatures
-
The following example assumes that all
DO_NOTHING
attributes share the distinct prefix ":
", and uses the prefix to define the allowed unsigned attributes. The client assumes that any attribute name with the ":
" prefix is excluded from the signatures. For more information, see Allowed unsigned attributes.final String unsignedAttrPrefix = ":";
- Step 4: Create the encryption configuration
-
The following example defines a
tableConfigs
Map that represents the encryption configuration for the DynamoDB table.This example specifies the DynamoDB table name as the logical table name. We strongly recommend specifying your DynamoDB table name as the logical table name when you first define your encryption configuration. For more information, see Encryption configuration in the AWS Database Encryption SDK for DynamoDB.
Note
To use searchable encryption or signed beacons, you must also include the SearchConfig in your encryption configuration.
final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>(); tableConfigs.put(ddbTableName, DynamoDbEnhancedTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .schemaOnEncrypt(tableSchema) .build());
- Step 5: Creates the
DynamoDbEncryptionInterceptor
-
The following example creates a new
DynamoDbEncryptionInterceptor
with thetableConfigs
from Step 4.final DynamoDbEncryptionInterceptor interceptor = DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor( CreateDynamoDbEncryptionInterceptorInput.builder() .tableEncryptionConfigs(tableConfigs) .build() );
- Step 6: Create a new AWS SDK DynamoDB client
-
The following example creates a new AWS SDK DynamoDB client using the
interceptor
from Step 5.final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(interceptor) .build()) .build();
- Step 7: Create the DynamoDB Enhanced Client and create a table
-
The following example creates the DynamoDB Enhanced Client using the AWS SDK DynamoDB client created in Step 6 and creates a table using the annotated data class.
final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
- Step 8: Encrypt and sign a table item
-
The following example puts an item into the DynamoDB table using the DynamoDB Enhanced Client. The item is encrypted and signed client-side before it is send to DynamoDB.
final SimpleClass item = new SimpleClass(); item.setPartitionKey("EnhancedPutGetExample"); item.setSortKey(0); item.setAttribute1("encrypt and sign me!"); item.setAttribute2("sign me!"); item.setAttribute3("ignore me!"); table.putItem(item);
Using the low-level DynamoDB API
The following example shows how to use the low-level DynamoDB API with an AWS KMS keyring to automatically encrypt and sign
items client-side with your DynamoDB PutItem
requests.
You can use any supported keyring, but we recommend using one of the AWS KMS keyrings whenever possible.
See the complete code sample: BasicPutGetExample.java
- Step 1: Create the AWS KMS keyring
-
The following example uses
CreateAwsKmsMrkMultiKeyring
to create an AWS KMS keyring with a symmetric encryption KMS key. TheCreateAwsKmsMrkMultiKeyring
method ensures that the keyring will correctly handle both single-Region and multi-Region keys.final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(kmsKeyId) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
- Step 2: Configure your attribute actions
-
The following example defines an
attributeActionsOnEncrypt
Map that represents sample attribute actions for a table item.Note
The following example does not define any attributes as
SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
. If you specify anySIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
attributes, then the partition and sort attributes must also beSIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
.final Map<String, CryptoAction> attributeActionsOnEncrypt = new HashMap<>(); // The partition attribute must be SIGN_ONLY attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_ONLY); // The sort attribute must be SIGN_ONLY attributeActionsOnEncrypt.put("sort_key", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN); attributeActionsOnEncrypt.put("attribute2", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put(":attribute3", CryptoAction.DO_NOTHING);
- Step 3: Define which attributes are excluded from the signatures
-
The following example assumes that all
DO_NOTHING
attributes share the distinct prefix ":
", and uses the prefix to define the allowed unsigned attributes. The client assumes that any attribute name with the ":
" prefix is excluded from the signatures. For more information, see Allowed unsigned attributes.final String unsignedAttrPrefix = ":";
- Step 4: Define the DynamoDB table encryption configuration
-
The following example defines a
tableConfigs
Map that represents the encryption configuration for this DynamoDB table.This example specifies the DynamoDB table name as the logical table name. We strongly recommend specifying your DynamoDB table name as the logical table name when you first define your encryption configuration. For more information, see Encryption configuration in the AWS Database Encryption SDK for DynamoDB.
Note
To use searchable encryption or signed beacons, you must also include the SearchConfig in your encryption configuration.
final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>(); final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .partitionKeyName("partition_key") .sortKeyName("sort_key") .attributeActionsOnEncrypt(attributeActionsOnEncrypt) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .build(); tableConfigs.put(ddbTableName, config);
- Step 5: Create the
DynamoDbEncryptionInterceptor
-
The following example creates the
DynamoDbEncryptionInterceptor
using thetableConfigs
from Step 4.DynamoDbEncryptionInterceptor interceptor = DynamoDbEncryptionInterceptor.builder() .config(DynamoDbTablesEncryptionConfig.builder() .tableEncryptionConfigs(tableConfigs) .build()) .build();
- Step 6: Create a new AWS SDK DynamoDB client
-
The following example creates a new AWS SDK DynamoDB client using the
interceptor
from Step 5.final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(interceptor) .build()) .build();
- Step 7: Encrypt and sign a DynamoDB table item
-
The following example defines an
item
Map that represents a sample table item and puts the item in the DynamoDB table. The item is encrypted and signed client-side before it is sent to DynamoDB.final HashMap<String, AttributeValue> item = new HashMap<>(); item.put("partition_key", AttributeValue.builder().s("BasicPutGetExample").build()); item.put("sort_key", AttributeValue.builder().n("0").build()); item.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build()); item.put("attribute2", AttributeValue.builder().s("sign me!").build()); item.put(":attribute3", AttributeValue.builder().s("ignore me!").build()); final PutItemRequest putRequest = PutItemRequest.builder() .tableName(ddbTableName) .item(item) .build(); final PutItemResponse putResponse = ddb.putItem(putRequest);
Using the lower-level DynamoDbItemEncryptor
The following example shows how to use the lower-level
DynamoDbItemEncryptor
with an AWS KMS keyring to directly encrypt and sign table items. The
DynamoDbItemEncryptor
does not put the item in your DynamoDB table.
You can use any supported keyring with the DynamoDB Enhanced Client, but we recommend using one of the AWS KMS keyrings whenever possible.
Note
The lower-level DynamoDbItemEncryptor
does not support searchable encryption. Use the
DynamoDbEncryptionInterceptor
with the low-level DynamoDB API to use
searchable encryption.
See the complete code sample: ItemEncryptDecryptExample.java
- Step 1: Create the AWS KMS keyring
-
The following example uses
CreateAwsKmsMrkMultiKeyring
to create an AWS KMS keyring with a symmetric encryption KMS key. TheCreateAwsKmsMrkMultiKeyring
method ensures that the keyring will correctly handle both single-Region and multi-Region keys.final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(kmsKeyId) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
- Step 2: Configure your attribute actions
-
The following example defines an
attributeActionsOnEncrypt
Map that represents sample attribute actions for a table item.Note
The following example does not define any attributes as
SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
. If you specify anySIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
attributes, then the partition and sort attributes must also beSIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
.final Map<String, CryptoAction> attributeActionsOnEncrypt = new HashMap<>(); // The partition attribute must be SIGN_ONLY attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_ONLY); // The sort attribute must be SIGN_ONLY attributeActionsOnEncrypt.put("sort_key", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN); attributeActionsOnEncrypt.put("attribute2", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put(":attribute3", CryptoAction.DO_NOTHING);
- Step 3: Define which attributes are excluded from the signatures
-
The following example assumes that all
DO_NOTHING
attributes share the distinct prefix ":
", and uses the prefix to define the allowed unsigned attributes. The client assumes that any attribute name with the ":
" prefix is excluded from the signatures. For more information, see Allowed unsigned attributes.final String unsignedAttrPrefix = ":";
- Step 4: Define the
DynamoDbItemEncryptor
configuration -
The following example defines the configuration for the
DynamoDbItemEncryptor
.This example specifies the DynamoDB table name as the logical table name. We strongly recommend specifying your DynamoDB table name as the logical table name when you first define your encryption configuration. For more information, see Encryption configuration in the AWS Database Encryption SDK for DynamoDB.
final DynamoDbItemEncryptorConfig config = DynamoDbItemEncryptorConfig.builder() .logicalTableName(ddbTableName) .partitionKeyName("partition_key") .sortKeyName("sort_key") .attributeActionsOnEncrypt(attributeActionsOnEncrypt) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .build();
- Step 5: Create the
DynamoDbItemEncryptor
-
The following example creates a new
DynamoDbItemEncryptor
using theconfig
from Step 4.final DynamoDbItemEncryptor itemEncryptor = DynamoDbItemEncryptor.builder() .DynamoDbItemEncryptorConfig(config) .build();
- Step 6: Directly encrypt and sign a table item
-
The following example directly encrypts and signs an item using the
DynamoDbItemEncryptor
. TheDynamoDbItemEncryptor
does not put the item in your DynamoDB table.final Map<String, AttributeValue> originalItem = new HashMap<>(); originalItem.put("partition_key", AttributeValue.builder().s("ItemEncryptDecryptExample").build()); originalItem.put("sort_key", AttributeValue.builder().n("0").build()); originalItem.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build()); originalItem.put("attribute2", AttributeValue.builder().s("sign me!").build()); originalItem.put(":attribute3", AttributeValue.builder().s("ignore me!").build()); final Map<String, AttributeValue> encryptedItem = itemEncryptor.EncryptItem( EncryptItemInput.builder() .plaintextItem(originalItem) .build() ).encryptedItem();