AWS Developer Blog

Client-side Encryption for Amazon DynamoDB

by Hanson Char | on | in Java | | Comments

We are thrilled to introduce one of the latest AWS Labs projects for enabling client-side encryption for Amazon DynamoDB in Java. This library is designed to support encryption and signing of your data when stored in Amazon DynamoDB.

A typical use of this library is when you are using DynamoDBMapper, where transparent encryption and signing of all objects serialized through the mapper can be enabled by configuring an AttributeEncryptor.

Getting Started

Suppose you have created (sample code) a DynamoDB table "MyStore", and want to store some Book objects. Let’s further suppose the security requirement involves classifying the attributes Title and Authors as sensitive information. Here is how the Book class might look like:

public class Book {
    private Integer id;
    private String title;
    private String ISBN;
    private Set bookAuthors;
    private String someProp;

    // Not encrypted because it is a hash key    
    public Integer getId() { return id;}
    public void setId(Integer id) { = id;}

    // Encrypted by default
    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }

    // Specifically not encrypted
    public String getISBN() { return ISBN; }
    public void setISBN(String ISBN) { this.ISBN = ISBN; }

    // Encrypted by default
    @DynamoDBAttribute(attributeName = "Authors")
    public Set<String> getBookAuthors() { return bookAuthors; }
    public void setBookAuthors(Set<String> bookAuthors) {
        this.bookAuthors = bookAuthors;

    // Not encrypted nor signed
    public String getSomeProp() { return someProp;}
    public void setSomeProp(String someProp) {this.someProp = someProp;}

For a typical use case of DynamoDBMapper, you can easily save and retrieve a Book object to and from Amazon DynamoDB without encryption (nor signing). For example,

AmazonDynamoDBClient client = new AmazonDynamoDBClient(...);
DynamoDBMapper mapper = new DynamoDBMapper(client);
Book book = new Book();
book.setTitle("Secret Book Title ");
// ... etc. setting other properties

// Saves the book unencrypted to DynamoDB;

// Loads the book back from DynamoDB
Book bookTo = new Book();
Book bookTo = mapper.load(bookTo);

To enable transparent encryption and signing, simply specify the necessary encryption material via an EncryptionMaterialsProvider. For example:

AmazonDynamoDBClient client = new AmazonDynamoDBClient(...);
SecretKey cek = ...;        // Content encrypting key
SecretKey macKey =  ...;    // Signing key
EncryptionMaterialsProvider provider = 
            new SymmetricStaticProvider(cek, macKey);
mapper = new DynamoDBMapper(client, DynamoDBMapperConfig.DEFAULT,
            new AttributeEncryptor(provider));
Book book = new Book();
book.setTitle("Secret Book Title ");
// ... etc. setting other properties

// Saves the book both encrypted and signed to DynamoDB;

// Loads the book both with signature verified and decrypted from DynamoDB
Book bookTo = new Book();
bookTo = mapper.load(bookTo);

Note that by default all attributes except the primary keys are both encrypted and signed for maximum security. To selectively disable encryption, you can use the annotation @DoNotEncrypt as shown in the Book class above. To disable both encryption and signing, you can use the annotation @DoNotTouch.

There are a variety of existing EncryptionMaterialsProvider implementations that you can use to provide the encryption material, including KeyStoreMaterialsProvider which makes use of a Java keystore. Alternatively, you can also plug in your own custom implementation.

For more information, head over to aws-dynamodb-encryption-java, and give it a spin. Happy crypto, and may the power of security and Amazon DynamoDB be with you!