Skip to content

Commit 7de5f5a

Browse files
committed
feat: Adds the CachingMostRecentProvider. Deprecates MostRecentProvider.
Time-based key re-authorization 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. The MostRecentProvider is deprecated. It is removed in 2.0.0. New deployments should use the CachingMostRecentProvider, and existing deployments should upgrade as soon as possible. See https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/most-recent-provider.html#mrp-versions for more details. This change also addresses interoperability issues between the Python and Java implementations of the DynamoDB Encryption Client.
1 parent 14c6a95 commit 7de5f5a

File tree

75 files changed

+11773
-2809
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+11773
-2809
lines changed

Diff for: CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
# Changelog
2+
## 1.15.0 -- 2021-02-04
3+
Adds the CachingMostRecentProvider and deprecates MostRecentProvider.
4+
5+
Time-based key reauthorization logic in MostRecentProvider did not re-authorize the use of the key
6+
after key usage permissions were changed at the key provider
7+
(for example AWS Key Management Service).
8+
This created the potential for keys to be used in the DynamoDB Encryption Client after permissions
9+
to do so were revoked.
10+
11+
CachingMostRecentProvider replaces MostRecentProvider and provides a cache entry TTL to reauthorize
12+
the key with the key provider.
13+
14+
MostRecentProvider is now deprecated, and is removed in 2.0.0.
15+
See https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/most-recent-provider.html#mrp-versions for more details.
16+
17+
1.15.0 also fixes interoperability issues between the Python and Java implementations of DynamoDB Encryption Client.
18+
219
## 1.14.1 -- 2019-10-14
320
Fixes `com.amazonaws:aws-dynamodb-encryption-java` so that it may be consumed
421
in mavenCentral.

Diff for: README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ You can download the [latest snapshot release][download] or pick it up from Mave
119119
<dependency>
120120
<groupId>com.amazonaws</groupId>
121121
<artifactId>aws-dynamodb-encryption-java</artifactId>
122-
<version>1.14.1</version>
122+
<version>1.15.0</version>
123123
</dependency>
124124
```
125125

@@ -177,4 +177,4 @@ For signing, the user specified signing key can be either symmetric or asymmetri
177177
[materialprovider]: sdk1/src/main/java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/EncryptionMaterialsProvider.java
178178
[privatekey]: http://docs.oracle.com/javase/7/docs/api/java/security/PrivateKey.html
179179
[secretkey]: http://docs.oracle.com/javase/7/docs/api/javax/crypto/SecretKey.html
180-
[download]: https://github.com/aws/aws-dynamodb-encryption-java/releases/tag/1.13.0
180+
[download]: https://github.com/aws/aws-dynamodb-encryption-java/releases

Diff for: common/pom.xml

-19
This file was deleted.

Diff for: ddej-build-tools/pom.xml

-39
This file was deleted.

Diff for: examples/pom.xml

+132-4
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,152 @@
88
<parent>
99
<groupId>software.amazon.cryptools</groupId>
1010
<artifactId>dynamodbencryptionclient-pom</artifactId>
11-
<version>0.1.0-SNAPSHOT</version>
11+
<version>1.15.0</version>
1212
</parent>
1313

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

20+
<properties>
21+
<sqlite4java.version>1.0.392</sqlite4java.version>
22+
<maven-failsafe-plugin.version>3.0.0-M3</maven-failsafe-plugin.version>
23+
<maven-surefire-plugin.version>3.0.0-M3</maven-surefire-plugin.version>
24+
</properties>
25+
2026
<dependencies>
2127
<dependency>
2228
<groupId>com.amazonaws</groupId>
2329
<artifactId>aws-dynamodb-encryption-java</artifactId>
24-
<version>1.13.0</version>
30+
<version>1.15.0</version>
31+
</dependency>
32+
33+
<dependency>
34+
<groupId>org.testng</groupId>
35+
<artifactId>testng</artifactId>
36+
<version>6.10</version>
37+
<scope>test</scope>
38+
</dependency>
39+
40+
<dependency>
41+
<groupId>com.amazonaws</groupId>
42+
<artifactId>DynamoDBLocal</artifactId>
43+
<version>1.10.5.1</version>
44+
<scope>test</scope>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>com.almworks.sqlite4java</groupId>
49+
<artifactId>sqlite4java</artifactId>
50+
<version>${sqlite4java.version}</version>
51+
<scope>test</scope>
52+
</dependency>
53+
54+
<dependency>
55+
<groupId>com.almworks.sqlite4java</groupId>
56+
<artifactId>libsqlite4java-osx</artifactId>
57+
<version>${sqlite4java.version}</version>
58+
<type>dylib</type>
59+
<scope>test</scope>
60+
</dependency>
61+
62+
<dependency>
63+
<groupId>com.almworks.sqlite4java</groupId>
64+
<artifactId>sqlite4java-win32-x64</artifactId>
65+
<version>${sqlite4java.version}</version>
66+
<type>dll</type>
67+
<scope>test</scope>
68+
</dependency>
69+
70+
<dependency>
71+
<groupId>com.almworks.sqlite4java</groupId>
72+
<artifactId>libsqlite4java-linux-amd64</artifactId>
73+
<type>so</type>
74+
<version>${sqlite4java.version}</version>
75+
<scope>test</scope>
2576
</dependency>
2677
</dependencies>
2778

79+
<!--Custom repository:-->
80+
<repositories>
81+
<repository>
82+
<id>dynamodb-local</id>
83+
<name>DynamoDB Local Release Repository</name>
84+
<url>https://s3-us-west-2.amazonaws.com/dynamodb-local/release</url>
85+
</repository>
86+
</repositories>
87+
2888
<build>
29-
<sourceDirectory>.</sourceDirectory>
89+
<plugins>
90+
<plugin>
91+
<groupId>org.apache.maven.plugins</groupId>
92+
<artifactId>maven-compiler-plugin</artifactId>
93+
<version>3.8.0</version>
94+
<configuration>
95+
<source>1.8</source>
96+
<target>1.8</target>
97+
</configuration>
98+
</plugin>
99+
100+
<plugin>
101+
<groupId>org.apache.maven.plugins</groupId>
102+
<artifactId>maven-dependency-plugin</artifactId>
103+
<version>3.1.1</version>
104+
<executions>
105+
<execution>
106+
<id>copy</id>
107+
<phase>test-compile</phase>
108+
<goals>
109+
<goal>copy-dependencies</goal>
110+
</goals>
111+
<configuration>
112+
<includeScope>test</includeScope>
113+
<includeTypes>so,dll,dylib</includeTypes>
114+
<outputDirectory>${project.build.directory}/test-lib</outputDirectory>
115+
</configuration>
116+
</execution>
117+
</executions>
118+
</plugin>
119+
120+
<plugin>
121+
<groupId>org.apache.maven.plugins</groupId>
122+
<artifactId>maven-surefire-plugin</artifactId>
123+
<version>${maven-surefire-plugin.version}</version>
124+
<configuration>
125+
<useSystemClassLoader>false</useSystemClassLoader>
126+
<systemProperties>
127+
<property>
128+
<name>sqlite4java.library.path</name>
129+
<value>${project.build.directory}/test-lib</value>
130+
</property>
131+
</systemProperties>
132+
</configuration>
133+
</plugin>
134+
135+
<plugin>
136+
<groupId>org.apache.maven.plugins</groupId>
137+
<artifactId>maven-failsafe-plugin</artifactId>
138+
<version>${maven-failsafe-plugin.version}</version>
139+
<configuration>
140+
<useSystemClassLoader>false</useSystemClassLoader>
141+
<systemProperties>
142+
<property>
143+
<name>sqlite4java.library.path</name>
144+
<value>${project.build.directory}/test-lib</value>
145+
</property>
146+
</systemProperties>
147+
</configuration>
148+
<executions>
149+
<execution>
150+
<goals>
151+
<goal>integration-test</goal>
152+
<goal>verify</goal>
153+
</goals>
154+
</execution>
155+
</executions>
156+
</plugin>
157+
</plugins>
30158
</build>
31159
</project>

Diff for: examples/com/amazonaws/examples/AsymmetricEncryptedItem.java renamed to examples/src/main/java/com/amazonaws/examples/AsymmetricEncryptedItem.java

+24-9
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,33 @@
3434
* For ease of the example, we create new random ones every time.
3535
*/
3636
public class AsymmetricEncryptedItem {
37-
37+
private static final String STRING_FIELD_NAME = "example";
38+
private static final String BINARY_FIELD_NAME = "and some binary";
39+
private static final String NUMBER_FIELD_NAME = "some numbers";
40+
private static final String IGNORED_FIELD_NAME = "leave me";
41+
3842
public static void main(String[] args) throws GeneralSecurityException {
3943
final String tableName = args[0];
4044
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
4145
keyGen.initialize(2048);
4246
// You should never use the same key for encryption and signing
4347
final KeyPair wrappingKeys = keyGen.generateKeyPair();
4448
final KeyPair signingKeys = keyGen.generateKeyPair();
45-
49+
4650
encryptRecord(tableName, wrappingKeys, signingKeys);
4751
}
4852

49-
private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPair signingKeys) throws GeneralSecurityException {
53+
public static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPair signingKeys) throws GeneralSecurityException {
5054
// Sample record to be encrypted
5155
final String partitionKeyName = "partition_attribute";
5256
final String sortKeyName = "sort_attribute";
5357
final Map<String, AttributeValue> record = new HashMap<>();
5458
record.put(partitionKeyName, new AttributeValue().withS("is this"));
5559
record.put(sortKeyName, new AttributeValue().withN("55"));
56-
record.put("example", new AttributeValue().withS("data"));
57-
record.put("some numbers", new AttributeValue().withN("99"));
58-
record.put("and some binary", new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
59-
record.put("leave me", new AttributeValue().withS("alone")); // We want to ignore this attribute
60+
record.put(STRING_FIELD_NAME, new AttributeValue().withS("data"));
61+
record.put(NUMBER_FIELD_NAME, new AttributeValue().withN("99"));
62+
record.put(BINARY_FIELD_NAME, new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
63+
record.put(IGNORED_FIELD_NAME, new AttributeValue().withS("alone")); // We want to ignore this attribute
6064

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

103+
// Encrypted record fields change as expected
104+
assert encrypted_record.get(STRING_FIELD_NAME).getB() != null; // the encrypted string is stored as bytes
105+
assert encrypted_record.get(NUMBER_FIELD_NAME).getB() != null; // the encrypted number is stored as bytes
106+
assert !record.get(BINARY_FIELD_NAME).getB().equals(encrypted_record.get(BINARY_FIELD_NAME).getB()); // the encrypted bytes have updated
107+
assert record.get(IGNORED_FIELD_NAME).getS().equals(encrypted_record.get(IGNORED_FIELD_NAME).getS()); // ignored field is left as is
108+
99109
// We could now put the encrypted item to DynamoDB just as we would any other item.
100110
// We're skipping it to to keep the example simpler.
101111

@@ -105,5 +115,10 @@ private static void encryptRecord(String tableName, KeyPair wrappingKeys, KeyPai
105115
// Decryption is identical. We'll pretend that we retrieved the record from DynamoDB.
106116
final Map<String, AttributeValue> decrypted_record = encryptor.decryptRecord(encrypted_record, actions, encryptionContext);
107117
System.out.println("Decrypted Record: " + decrypted_record);
108-
}
118+
119+
// The decrypted fields match the original fields before encryption
120+
assert record.get(STRING_FIELD_NAME).getS().equals(decrypted_record.get(STRING_FIELD_NAME).getS());
121+
assert record.get(NUMBER_FIELD_NAME).getN().equals(decrypted_record.get(NUMBER_FIELD_NAME).getN());
122+
assert record.get(BINARY_FIELD_NAME).getB().equals(decrypted_record.get(BINARY_FIELD_NAME).getB());
123+
}
109124
}

0 commit comments

Comments
 (0)