Skip to content

feat: Adds the CachingMostRecentProvider. Deprecates MostRecentProvider. #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
# Changelog
## 1.15.0 -- 2021-02-04
Adds the CachingMostRecentProvider and deprecates MostRecentProvider.

Time-based key reauthorization logic in MostRecentProvider did not re-authorize the use of the key
after key usage permissions were changed at the key provider
(for example AWS Key Management Service).
This created the potential for keys to be used in the DynamoDB Encryption Client after permissions
to do so were revoked.

CachingMostRecentProvider replaces MostRecentProvider and provides a cache entry TTL to reauthorize
the key with the key provider.

MostRecentProvider is now deprecated, and is removed in 2.0.0.
See https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/most-recent-provider.html#mrp-versions for more details.

1.15.0 also fixes interoperability issues between the Python and Java implementations of DynamoDB Encryption Client.

## 1.14.1 -- 2019-10-14
Fixes `com.amazonaws:aws-dynamodb-encryption-java` so that it may be consumed
in mavenCentral.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ You can download the [latest snapshot release][download] or pick it up from Mave
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-dynamodb-encryption-java</artifactId>
<version>1.14.1</version>
<version>1.15.0</version>
</dependency>
```

Expand Down Expand Up @@ -177,4 +177,4 @@ For signing, the user specified signing key can be either symmetric or asymmetri
[materialprovider]: sdk1/src/main/java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/EncryptionMaterialsProvider.java
[privatekey]: http://docs.oracle.com/javase/7/docs/api/java/security/PrivateKey.html
[secretkey]: http://docs.oracle.com/javase/7/docs/api/javax/crypto/SecretKey.html
[download]: https://github.com/aws/aws-dynamodb-encryption-java/releases/tag/1.13.0
[download]: https://github.com/aws/aws-dynamodb-encryption-java/releases
19 changes: 0 additions & 19 deletions common/pom.xml

This file was deleted.

39 changes: 0 additions & 39 deletions ddej-build-tools/pom.xml

This file was deleted.

136 changes: 132 additions & 4 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,152 @@
<parent>
<groupId>software.amazon.cryptools</groupId>
<artifactId>dynamodbencryptionclient-pom</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>1.15.0</version>
</parent>

<artifactId>dynamodbencryptionclient-sdk1examples</artifactId>
<packaging>jar</packaging>
<version>0.1.0-SNAPSHOT</version>
<version>1.15.0</version>
<name>aws-dynamodb-encryption-java :: SDK1 Examples</name>
<description>Examples for AWS DynamoDB Encryption Client for AWS Java SDK v1</description>

<properties>
<sqlite4java.version>1.0.392</sqlite4java.version>
<maven-failsafe-plugin.version>3.0.0-M3</maven-failsafe-plugin.version>
<maven-surefire-plugin.version>3.0.0-M3</maven-surefire-plugin.version>
</properties>

<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-dynamodb-encryption-java</artifactId>
<version>1.13.0</version>
<version>1.15.0</version>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.10</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>DynamoDBLocal</artifactId>
<version>1.10.5.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.almworks.sqlite4java</groupId>
<artifactId>sqlite4java</artifactId>
<version>${sqlite4java.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.almworks.sqlite4java</groupId>
<artifactId>libsqlite4java-osx</artifactId>
<version>${sqlite4java.version}</version>
<type>dylib</type>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.almworks.sqlite4java</groupId>
<artifactId>sqlite4java-win32-x64</artifactId>
<version>${sqlite4java.version}</version>
<type>dll</type>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.almworks.sqlite4java</groupId>
<artifactId>libsqlite4java-linux-amd64</artifactId>
<type>so</type>
<version>${sqlite4java.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<!--Custom repository:-->
<repositories>
<repository>
<id>dynamodb-local</id>
<name>DynamoDB Local Release Repository</name>
<url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</url>
</repository>
</repositories>

<build>
<sourceDirectory>.</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy</id>
<phase>test-compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>test</includeScope>
<includeTypes>so,dll,dylib</includeTypes>
<outputDirectory>${project.build.directory}/test-lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<systemProperties>
<property>
<name>sqlite4java.library.path</name>
<value>${project.build.directory}/test-lib</value>
</property>
</systemProperties>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<systemProperties>
<property>
<name>sqlite4java.library.path</name>
<value>${project.build.directory}/test-lib</value>
</property>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,33 @@
* For ease of the example, we create new random ones every time.
*/
public class AsymmetricEncryptedItem {

private static final String STRING_FIELD_NAME = "example";
private static final String BINARY_FIELD_NAME = "and some binary";
private static final String NUMBER_FIELD_NAME = "some numbers";
private static final String IGNORED_FIELD_NAME = "leave me";

public static void main(String[] args) throws GeneralSecurityException {
final String tableName = args[0];
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
// You should never use the same key for encryption and signing
final KeyPair wrappingKeys = keyGen.generateKeyPair();
final KeyPair signingKeys = keyGen.generateKeyPair();

encryptRecord(tableName, wrappingKeys, signingKeys);
}

private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPair signingKeys) throws GeneralSecurityException {
public static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPair signingKeys) throws GeneralSecurityException {
// Sample record to be encrypted
final String partitionKeyName = "partition_attribute";
final String sortKeyName = "sort_attribute";
final Map<String, AttributeValue> record = new HashMap<>();
record.put(partitionKeyName, new AttributeValue().withS("is this"));
record.put(sortKeyName, new AttributeValue().withN("55"));
record.put("example", new AttributeValue().withS("data"));
record.put("some numbers", new AttributeValue().withN("99"));
record.put("and some binary", new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
record.put("leave me", new AttributeValue().withS("alone")); // We want to ignore this attribute
record.put(STRING_FIELD_NAME, new AttributeValue().withS("data"));
record.put(NUMBER_FIELD_NAME, new AttributeValue().withN("99"));
record.put(BINARY_FIELD_NAME, new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
record.put(IGNORED_FIELD_NAME, new AttributeValue().withS("alone")); // We want to ignore this attribute

// Set up our configuration and clients. All of this is thread-safe and can be reused across calls.
// Provider Configuration
Expand All @@ -82,7 +86,7 @@ private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPai
// Partition and sort keys must not be encrypted but should be signed
actions.put(attributeName, signOnly);
break;
case "leave me":
case IGNORED_FIELD_NAME:
// For this example, we are neither signing nor encrypting this field
break;
default:
Expand All @@ -96,6 +100,12 @@ private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPai
// Encrypt the plaintext record directly
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);

// Encrypted record fields change as expected
assert encrypted_record.get(STRING_FIELD_NAME).getB() != null; // the encrypted string is stored as bytes
assert encrypted_record.get(NUMBER_FIELD_NAME).getB() != null; // the encrypted number is stored as bytes
assert !record.get(BINARY_FIELD_NAME).getB().equals(encrypted_record.get(BINARY_FIELD_NAME).getB()); // the encrypted bytes have updated
assert record.get(IGNORED_FIELD_NAME).getS().equals(encrypted_record.get(IGNORED_FIELD_NAME).getS()); // ignored field is left as is

// We could now put the encrypted item to DynamoDB just as we would any other item.
// We're skipping it to to keep the example simpler.

Expand All @@ -105,5 +115,10 @@ private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPai
// Decryption is identical. We'll pretend that we retrieved the record from DynamoDB.
final Map<String, AttributeValue> decrypted_record = encryptor.decryptRecord(encrypted_record, actions, encryptionContext);
System.out.println("Decrypted Record: " + decrypted_record);
}

// The decrypted fields match the original fields before encryption
assert record.get(STRING_FIELD_NAME).getS().equals(decrypted_record.get(STRING_FIELD_NAME).getS());
assert record.get(NUMBER_FIELD_NAME).getN().equals(decrypted_record.get(NUMBER_FIELD_NAME).getN());
assert record.get(BINARY_FIELD_NAME).getB().equals(decrypted_record.get(BINARY_FIELD_NAME).getB());
}
}
Loading