Skip to content

Commit 8bdb1d4

Browse files
Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders. (#151)
* Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders. * Update example code to use keyrings * Using try-with-resources for AwsCrypto streams * Splitting MKP and keyring unit tests * Making decryptData with ParsedCiphertext public * Mark KeyStoreProvider as deprecated * Reword some comments on the Basic Encryption example * Add test for compability of Keyrings with MasterKeyProviders * Create individual request types for each AwsCrypto method * Make EncryptionMaterials, DecryptionMaterials and KeyringTrace immutable * Rename KmsKeying and related classes to AwsKmsKeyring * Create builders for the standard keyrings * Create AwsKmsCmkId type to represent AWS KMS Key Ids * Add factory methods to Keyring builders * Add comment on not making a defensive copy of plaintext/ciphertext * Limit ability to create discovery AWS KMS Keyrings to explicit creation * Add withKeyring to CachingCMM builder * Fix DecryptRequestTest * Fix Junit 4 assertions in JUnit5 tests * Renaming StaticKeyring to TestKeyring * Adding convenience methods the create builders internally * Updating wording and adding more Deprecated annotations * Enable AwsKms Client Caching by default to match KmsMasterKeyProvider * Making tests opt-out instead of opt-in and update TestVectorRunner (#154) * Making tests opt-out instead of opt-in and update TestVectorRunner JUnit5 doesn't support test suites yet (see junit-team/junit5#744) and the existing test suites do not support the new JUnit5 tests that are being used for keyrings. This change removes the test suites, and configures Maven to include all tests except those marked with certain JUnit tags. Additionally, this change updates the TestVectorRunner to also test Keyrings and removes the redundant XCompat tests. * Client caching is now enabled by default in AwsKmsClientSupplier * Rename slow tag to ad_hoc and fix TestVectorRunner * Renaming StandardKeyring builder methods and other minors changes * Fixing test * Updating tests to use assertThrows * Additional example code for Keyrings (#155) * Additional example code for Keyrings * Updating wording * Remove AWS from AWS KMS keyring and make keyring lowercase
1 parent 1ee9643 commit 8bdb1d4

File tree

97 files changed

+4678
-1529
lines changed

Some content is hidden

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

97 files changed

+4678
-1529
lines changed

pom.xml

+44-11
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
<dependency>
5656
<groupId>org.junit.jupiter</groupId>
57-
<artifactId>junit-jupiter-engine</artifactId>
57+
<artifactId>junit-jupiter</artifactId>
5858
<version>5.5.2</version>
5959
<scope>test</scope>
6060
</dependency>
@@ -80,6 +80,19 @@
8080
<scope>test</scope>
8181
</dependency>
8282

83+
<dependency>
84+
<groupId>com.amazonaws</groupId>
85+
<artifactId>aws-lambda-java-core</artifactId>
86+
<version>1.2.0</version>
87+
<scope>test</scope>
88+
</dependency>
89+
90+
<dependency>
91+
<groupId>com.amazonaws</groupId>
92+
<artifactId>aws-lambda-java-events</artifactId>
93+
<version>2.2.7</version>
94+
<scope>test</scope>
95+
</dependency>
8396

8497
<dependency>
8598
<groupId>com.google.code.findbugs</groupId>
@@ -197,7 +210,7 @@
197210
</profile>
198211

199212
<profile>
200-
<id>full-test-suite</id>
213+
<id>test-suite</id>
201214
<activation>
202215
<activeByDefault>true</activeByDefault>
203216
</activation>
@@ -208,30 +221,50 @@
208221
<artifactId>maven-surefire-plugin</artifactId>
209222
<version>2.22.0</version>
210223
<configuration>
211-
<includes>
212-
<include>**/AllTestsSuite.java</include>
213-
</includes>
224+
<excludedGroups>ad_hoc</excludedGroups>
214225
</configuration>
215226
</plugin>
216227
</plugins>
217228
</build>
218229
</profile>
219230

231+
<!-- This test profile is intended to assist in rapid development; it filters out some of the slower,
232+
more exhaustive tests in the overall test suite to allow for a rapid edit-test cycle. -->
220233
<profile>
221234
<id>fast-tests-only</id>
222-
<activation>
223-
<activeByDefault>false</activeByDefault>
224-
</activation>
225235
<build>
226236
<plugins>
227237
<plugin>
228238
<groupId>org.apache.maven.plugins</groupId>
229239
<artifactId>maven-surefire-plugin</artifactId>
230240
<version>2.22.0</version>
231241
<configuration>
232-
<includes>
233-
<include>**/FastTestsOnlySuite.java</include>
234-
</includes>
242+
<excludedGroups>ad_hoc, integration</excludedGroups>
243+
<systemPropertyVariables>
244+
<fastTestsOnly>true</fastTestsOnly>
245+
</systemPropertyVariables>
246+
<!-- Require that this fast suite completes relatively quickly. If you're seeing
247+
this timeout get hit, it's time to pare down tests some more. As a general rule of
248+
thumb, we should avoid any single test taking more than 10s, and try to keep the
249+
number of such slow tests to a minimum. -->
250+
<forkedProcessTimeoutInSeconds>120</forkedProcessTimeoutInSeconds>
251+
</configuration>
252+
</plugin>
253+
</plugins>
254+
</build>
255+
</profile>
256+
257+
<!-- This test profile will run only the integration tests. -->
258+
<profile>
259+
<id>integration</id>
260+
<build>
261+
<plugins>
262+
<plugin>
263+
<groupId>org.apache.maven.plugins</groupId>
264+
<artifactId>maven-surefire-plugin</artifactId>
265+
<version>2.22.0</version>
266+
<configuration>
267+
<groups>integration</groups>
235268
</configuration>
236269
</plugin>
237270
</plugins>

src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java

+38-29
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919
import java.util.Map;
2020

2121
import com.amazonaws.encryptionsdk.AwsCrypto;
22-
import com.amazonaws.encryptionsdk.CryptoResult;
23-
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
24-
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
22+
import com.amazonaws.encryptionsdk.AwsCryptoResult;
23+
import com.amazonaws.encryptionsdk.DecryptRequest;
24+
import com.amazonaws.encryptionsdk.EncryptRequest;
25+
import com.amazonaws.encryptionsdk.keyrings.Keyring;
26+
import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings;
27+
import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId;
2528

2629
/**
2730
* <p>
28-
* Encrypts and then decrypts data using an AWS KMS customer master key.
31+
* Encrypts and then decrypts data using an AWS Key Management Service (AWS KMS) customer master key.
2932
*
3033
* <p>
3134
* Arguments:
@@ -39,48 +42,54 @@ public class BasicEncryptionExample {
3942
private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);
4043

4144
public static void main(final String[] args) {
42-
final String keyArn = args[0];
43-
44-
encryptAndDecrypt(keyArn);
45+
encryptAndDecrypt(AwsKmsCmkId.fromString(args[0]));
4546
}
4647

47-
static void encryptAndDecrypt(final String keyArn) {
48+
static void encryptAndDecrypt(final AwsKmsCmkId keyArn) {
4849
// 1. Instantiate the SDK
4950
final AwsCrypto crypto = new AwsCrypto();
5051

51-
// 2. Instantiate a KMS master key provider
52-
final KmsMasterKeyProvider masterKeyProvider = KmsMasterKeyProvider.builder().withKeysForEncryption(keyArn).build();
52+
// 2. Instantiate a KMS keyring. Supply the key ARN for the generator key
53+
// that generates a data key. While using a key ARN is a best practice,
54+
// for encryption operations you can also use an alias name or alias ARN.
55+
final Keyring keyring = StandardKeyrings.awsKms(keyArn);
5356

5457
// 3. Create an encryption context
5558
//
56-
// Most encrypted data should have an associated encryption context
57-
// to protect integrity. This sample uses placeholder values.
59+
// Most encrypted data should have an associated encryption context
60+
// to protect integrity. This sample uses placeholder values.
5861
//
59-
// For more information see:
60-
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
62+
// For more information see:
63+
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
6164
final Map<String, String> encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue");
6265

63-
// 4. Encrypt the data
64-
final CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(masterKeyProvider, EXAMPLE_DATA, encryptionContext);
66+
// 4. Encrypt the data with the keyring and encryption context
67+
final AwsCryptoResult<byte[]> encryptResult = crypto.encrypt(
68+
EncryptRequest.builder()
69+
.keyring(keyring)
70+
.encryptionContext(encryptionContext)
71+
.plaintext(EXAMPLE_DATA).build());
6572
final byte[] ciphertext = encryptResult.getResult();
6673

67-
// 5. Decrypt the data
68-
final CryptoResult<byte[], KmsMasterKey> decryptResult = crypto.decryptData(masterKeyProvider, ciphertext);
74+
// 5. Decrypt the data. You can use the same keyring to encrypt and decrypt, but for decryption
75+
// the key IDs must be in the key ARN format.
76+
final AwsCryptoResult<byte[]> decryptResult = crypto.decrypt(
77+
DecryptRequest.builder()
78+
.keyring(keyring)
79+
.ciphertext(ciphertext).build());
6980

70-
// 6. Before verifying the plaintext, verify that the customer master key that
71-
// was used in the encryption operation was the one supplied to the master key provider.
72-
if (!decryptResult.getMasterKeyIds().get(0).equals(keyArn)) {
81+
// 6. To verify the CMK that was actually used in the decrypt operation, inspect the keyring trace.
82+
if(!decryptResult.getKeyringTrace().getEntries().get(0).getKeyName().equals(keyArn.toString())) {
7383
throw new IllegalStateException("Wrong key ID!");
7484
}
7585

76-
// 7. Also, verify that the encryption context in the result contains the
77-
// encryption context supplied to the encryptData method. Because the
78-
// SDK can add values to the encryption context, don't require that
79-
// the entire context matches.
80-
if (!encryptionContext.entrySet().stream()
81-
.allMatch(e -> e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey())))) {
82-
throw new IllegalStateException("Wrong Encryption Context!");
83-
}
86+
// 7. To verify that the encryption context used to decrypt the data was the encryption context you expected,
87+
// examine the encryption context in the result. This helps to ensure that you decrypted the ciphertext that
88+
// you intended.
89+
//
90+
// When verifying, test that your expected encryption context is a subset of the actual encryption context,
91+
// not an exact match. The Encryption SDK adds the signing key to the encryption context when appropriate.
92+
assert decryptResult.getEncryptionContext().get("ExampleContextKey").equals("ExampleContextValue");
8493

8594
// 8. Verify that the decrypted plaintext matches the original plaintext
8695
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);

0 commit comments

Comments
 (0)