Skip to content

Commit 4678ffa

Browse files
committed
feat!: Updates to the AWS Encryption SDK.
This change includes fixes for issues that were reported by Thai Duong from Google's Security team, and for issues that were identified by AWS Cryptography. BREAKING CHANGE: AWS KMS KeyIDs must be specified explicitly or Discovery mode explicitly chosen. Key committing suites are now default. CommitmentPolicy requires commitment by default. See: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/migration.html
1 parent 4d69c2a commit 4678ffa

File tree

47 files changed

+1067
-1310
lines changed

Some content is hidden

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

47 files changed

+1067
-1310
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ public class StringExample {
9191
data = args[1];
9292

9393
// Instantiate the SDK
94-
final AwsCrypto crypto = AwsCrypto.builder()
95-
.withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt)
96-
.build();
94+
final AwsCrypto crypto = AwsCrypto.standard();
9795

9896
// Set up the master key provider
9997
final KmsMasterKeyProvider prov = KmsMasterKeyProvider.builder().buildStrict(keyArn);

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.amazonaws</groupId>
66
<artifactId>aws-encryption-sdk-java</artifactId>
7-
<version>1.7.0</version>
7+
<version>2.0.0</version>
88
<packaging>jar</packaging>
99

1010
<name>aws-encryption-sdk-java</name>

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,21 @@ public static void main(final String[] args) {
3636
}
3737

3838
static void encryptAndDecrypt(final String keyArn) {
39-
// 1. Instantiate the SDK with a specific commitment policy.
40-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
41-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
39+
// 1. Instantiate the SDK
40+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
41+
// which enforces that this client only encrypts using committing algorithm suites and enforces
42+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
43+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
44+
// or `AwsCrypto.standard()`.
45+
final AwsCrypto crypto = AwsCrypto.builder()
46+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
47+
.build();
4248

43-
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict()
49+
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict().
4450
// In strict mode, the AWS KMS master key provider encrypts and decrypts only by using the key
4551
// indicated by keyArn.
4652
// To encrypt and decrypt with this master key provider, use an AWS KMS key ARN to identify the CMKs.
47-
// The decrypt operation doesn't work with any other key identifier in strict mode.
53+
// In strict mode, the decrypt operation requires a key ARN.
4854
final KmsMasterKeyProvider keyProvider = KmsMasterKeyProvider.builder().buildStrict(keyArn);
4955

5056
// 3. Create an encryption context

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@ public static void main(final String[] args) {
4545
}
4646

4747
static void encryptAndDecrypt(final String keyName, final String partition, final String accountId) {
48-
// 1. Instantiate the SDK with a specific commitment policy.
49-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
50-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
48+
// 1. Instantiate the SDK
49+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
50+
// which enforces that this client only encrypts using committing algorithm suites and enforces
51+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
52+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
53+
// or `AwsCrypto.standard()`.
54+
final AwsCrypto crypto = AwsCrypto.builder()
55+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
56+
.build();
5157

5258
// 2. Instantiate an AWS KMS master key provider for encryption.
5359
//

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

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,16 @@ public static void main(final String[] args) throws Exception {
6666
}
6767

6868
private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception {
69-
// Encrypt with the AWS KMS CMK and the escrowed public key
70-
// 1. Instantiate the SDK with a specific commitment policy.
71-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
72-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
69+
// Encrypt with the KMS CMK and the escrowed public key
70+
// 1. Instantiate the SDK
71+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
72+
// which enforces that this client only encrypts using committing algorithm suites and enforces
73+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
74+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
75+
// or `AwsCrypto.standard()`.
76+
final AwsCrypto crypto = AwsCrypto.builder()
77+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
78+
.build();
7379

7480
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict()
7581
//
@@ -102,8 +108,15 @@ private static void standardDecrypt(final String kmsArn, final String fileName)
102108
// Decrypt with the AWS KMS CMK and the escrow public key. You can use a combined provider,
103109
// as shown here, or just the AWS KMS master key provider.
104110

105-
// 1. Instantiate the SDK
106-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
111+
// 1. Instantiate the SDK.
112+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
113+
// which enforces that this client only encrypts using committing algorithm suites and enforces
114+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
115+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
116+
// or `AwsCrypto.standard()`.
117+
final AwsCrypto crypto = AwsCrypto.builder()
118+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
119+
.build();
107120

108121
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict()
109122
//
@@ -136,7 +149,7 @@ private static void escrowDecrypt(final String fileName) throws Exception {
136149
// This method does not call AWS KMS.
137150

138151
// 1. Instantiate the SDK
139-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
152+
final AwsCrypto crypto = AwsCrypto.standard();
140153

141154
// 2. Instantiate a JCE master key provider
142155
// This method call uses the escrowed private key, not null

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ public static void main(String[] args) throws IOException {
4747
// Create a JCE master key provider using the random key and an AES-GCM encryption algorithm
4848
JceMasterKey masterKey = JceMasterKey.getInstance(cryptoKey, "Example", "RandomKey", "AES/GCM/NoPadding");
4949

50-
// Instantiate the SDK with a specific commitment policy.
51-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
52-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
50+
// Instantiate the SDK.
51+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
52+
// which enforces that this client only encrypts using committing algorithm suites and enforces
53+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
54+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
55+
// or `AwsCrypto.standard()`.
56+
final AwsCrypto crypto = AwsCrypto.builder()
57+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
58+
.build();
5359

5460
// Create an encryption context to identify this ciphertext
5561
Map<String, String> context = Collections.singletonMap("Example", "FileStreaming");

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ public static void main(final String[] args) {
4141
}
4242

4343
static void encryptAndDecrypt(final String keyArn1, final String keyArn2) {
44-
// 1. Instantiate the SDK with a specific commitment policy.
45-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
46-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
44+
// Instantiate the SDK.
45+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
46+
// which enforces that this client only encrypts using committing algorithm suites and enforces
47+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
48+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
49+
// or `AwsCrypto.standard()`.
50+
final AwsCrypto crypto = AwsCrypto.builder()
51+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
52+
.build();
4753

4854
// 2. Instantiate an AWS KMS master key provider to encrypt with
4955
// In strict mode (`buildStrict`), the AWS KMS master key provider encrypts and decrypts only by using the

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,15 @@ public static void main(final String[] args) {
4949
}
5050

5151
static void encryptAndDecrypt(final String keyName, final String partition, final String accountId, final String region) {
52-
// 1. Instantiate the SDK with a specific commitment policy.
53-
// ForbidEncryptAllowDecrypt is the only available policy in 1.7.0.
54-
final AwsCrypto crypto = AwsCrypto.builder().withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt).build();
52+
// Instantiate the SDK.
53+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
54+
// which enforces that this client only encrypts using committing algorithm suites and enforces
55+
// that this client will only decrypt encrypted messages that were created with a committing algorithm suite.
56+
// This is the default commitment policy if you build the client with `AwsCrypto.builder().build()`
57+
// or `AwsCrypto.standard()`.
58+
final AwsCrypto crypto = AwsCrypto.builder()
59+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
60+
.build();
5561

5662
// 2. Instantiate the AWS KMS client for the desired region
5763
final AWSKMS kmsClient = AWSKMSClientBuilder.standard().withRegion(region).build();
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.amazonaws.crypto.examples;
5+
6+
import java.nio.charset.StandardCharsets;
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.Map;
10+
11+
import com.amazonaws.encryptionsdk.AwsCrypto;
12+
import com.amazonaws.encryptionsdk.CommitmentPolicy;
13+
import com.amazonaws.encryptionsdk.CryptoResult;
14+
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
15+
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
16+
17+
/**
18+
* <p>
19+
* Configures a client with a specific commitment policy, then
20+
* encrypts and decrypts data using an AWS KMS customer master key.
21+
*
22+
* This configuration should only be used as part of a migration from version 1.x to 2.x, or for advanced users
23+
* with specialized requirements. We recommend that AWS Encryption SDK users use the default commitment policy
24+
* whenever possible.
25+
*
26+
* <p>
27+
* Arguments:
28+
* <ol>
29+
* <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master
30+
* key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
31+
* </ol>
32+
*/
33+
public class SetCommitmentPolicyExample {
34+
35+
private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);
36+
37+
public static void main(final String[] args) {
38+
final String keyArn = args[0];
39+
40+
encryptAndDecrypt(keyArn);
41+
}
42+
43+
static void encryptAndDecrypt(final String keyArn) {
44+
// 1. Instantiate the SDK with a specific commitment policy
45+
//
46+
// `withCommitmentPolicy(CommitmentPolicy)` configures the client with
47+
// a commitment policy that dictates whether the client is required to encrypt
48+
// using committing algorithms and whether the client must require that the messages
49+
// it decrypts were encrypted using committing algorithms.
50+
// In this example, we set the commitment policy to `ForbidEncryptAllowDecrypt`.
51+
// This policy enforces that the client writes using non-committing algorithms,
52+
// and allows decrypting of messages created with committing algorithms.
53+
//
54+
// If this value is not set, the client is configured to use our recommended default:
55+
// `RequireEncryptRequireDecrypt`.
56+
// This policy enforces that the client uses committing algorithms
57+
// to encrypt and enforces that the client only decrypts messages created with committing algorithms.
58+
// We recommend using the default whenever possible.
59+
final AwsCrypto crypto = AwsCrypto.builder()
60+
.withCommitmentPolicy(CommitmentPolicy.ForbidEncryptAllowDecrypt)
61+
.build();
62+
63+
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict()
64+
// In strict mode, the AWS KMS master key provider encrypts and decrypts only by using the key
65+
// indicated by keyArn.
66+
// To encrypt and decrypt with this master key provider, use an AWS KMS key ARN to identify the CMKs.
67+
// In strict mode, the decrypt operation requires a key ARN.
68+
final KmsMasterKeyProvider keyProvider = KmsMasterKeyProvider.builder().buildStrict(keyArn);
69+
70+
// 3. Create an encryption context
71+
// Most encrypted data should have an associated encryption context
72+
// to protect integrity. This sample uses placeholder values.
73+
// For more information see:
74+
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
75+
final Map<String, String> encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue");
76+
77+
// 4. Encrypt the data
78+
final CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(keyProvider, EXAMPLE_DATA, encryptionContext);
79+
final byte[] ciphertext = encryptResult.getResult();
80+
81+
// 5. Decrypt the data
82+
final CryptoResult<byte[], KmsMasterKey> decryptResult = crypto.decryptData(keyProvider, ciphertext);
83+
84+
// 6. Verify that the encryption context in the result contains the
85+
// encryption context supplied to the encryptData method. Because the
86+
// SDK can add values to the encryption context, don't require that
87+
// the entire context matches.
88+
if (!encryptionContext.entrySet().stream()
89+
.allMatch(e -> e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey())))) {
90+
throw new IllegalStateException("Wrong Encryption Context!");
91+
}
92+
93+
// 7. Verify that the decrypted plaintext matches the original plaintext
94+
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
95+
}
96+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.amazonaws.crypto.examples;
5+
6+
import java.nio.charset.StandardCharsets;
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.Map;
10+
11+
import com.amazonaws.encryptionsdk.AwsCrypto;
12+
import com.amazonaws.encryptionsdk.CryptoAlgorithm;
13+
import com.amazonaws.encryptionsdk.CryptoResult;
14+
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
15+
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
16+
17+
/**
18+
* <p>
19+
* Configures a client with a specific encryption algorithm, then
20+
* encrypts and decrypts data using that encryption algorithm and
21+
* an AWS KMS customer master key.
22+
*
23+
* <p>
24+
* Arguments:
25+
* <ol>
26+
* <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master
27+
* key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
28+
* </ol>
29+
*/
30+
public class SetEncryptionAlgorithmExample {
31+
32+
private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);
33+
34+
public static void main(final String[] args) {
35+
final String keyArn = args[0];
36+
37+
encryptAndDecrypt(keyArn);
38+
}
39+
40+
static void encryptAndDecrypt(final String keyArn) {
41+
// 1. Instantiate the SDK with the algorithm for encryption
42+
//
43+
// `withEncryptionAlgorithm(cryptoAlgorithm)` configures the client to encrypt
44+
// using a specified encryption algorithm.
45+
// This example sets the encryption algorithm to
46+
// `CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY`,
47+
// which is an algorithm that does not contain message signing.
48+
//
49+
// If this value is not set, the client encrypts with the recommended default:
50+
// `CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384`.
51+
// We recommend using the default whenever possible.
52+
// For a description of our supported algorithms, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/supported-algorithms.html
53+
//
54+
// You can update the encryption algorithm after constructing the client
55+
// by using `crypto.setEncryptionAlgorithm(CryptoAlgorithm)`.
56+
final AwsCrypto crypto = AwsCrypto.builder()
57+
.withEncryptionAlgorithm(CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY)
58+
.build();
59+
60+
// 2. Instantiate an AWS KMS master key provider in strict mode using buildStrict().
61+
// In strict mode, the AWS KMS master key provider encrypts and decrypts only by using the key
62+
// indicated by keyArn.
63+
// To encrypt and decrypt with this master key provider, use an AWS KMS key ARN to identify the CMKs.
64+
// In strict mode, the decrypt operation requires a key ARN.
65+
final KmsMasterKeyProvider keyProvider = KmsMasterKeyProvider.builder().buildStrict(keyArn);
66+
67+
// 3. Create an encryption context
68+
// Most encrypted data should have an associated encryption context
69+
// to protect integrity. This sample uses placeholder values.
70+
// For more information see:
71+
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
72+
final Map<String, String> encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue");
73+
74+
// 4. Encrypt the data
75+
final CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(keyProvider, EXAMPLE_DATA, encryptionContext);
76+
final byte[] ciphertext = encryptResult.getResult();
77+
78+
// 5. Decrypt the data
79+
final CryptoResult<byte[], KmsMasterKey> decryptResult = crypto.decryptData(keyProvider, ciphertext);
80+
81+
// 6. Verify that the encryption context in the result contains the
82+
// encryption context supplied to the encryptData method. Because the
83+
// SDK can add values to the encryption context, don't require that
84+
// the entire context matches.
85+
if (!encryptionContext.entrySet().stream()
86+
.allMatch(e -> e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey())))) {
87+
throw new IllegalStateException("Wrong Encryption Context!");
88+
}
89+
90+
// 7. Verify that the decrypted plaintext matches the original plaintext
91+
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
92+
}
93+
}

0 commit comments

Comments
 (0)