Skip to content

Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders. #151

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 28 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6bb85a0
Incorporate Keyrings into AwsCrypto and deprecate MasterKeyProviders.
WesleyRosenblum Jan 17, 2020
63ff149
Update example code to use keyrings
WesleyRosenblum Jan 21, 2020
d444f52
Using try-with-resources for AwsCrypto streams
WesleyRosenblum Jan 23, 2020
0a3e6e3
Splitting MKP and keyring unit tests
WesleyRosenblum Jan 23, 2020
30c51a9
Making decryptData with ParsedCiphertext public
WesleyRosenblum Jan 23, 2020
4d8614f
Mark KeyStoreProvider as deprecated
WesleyRosenblum Jan 24, 2020
400f521
Reword some comments on the Basic Encryption example
WesleyRosenblum Jan 27, 2020
59e3045
Add test for compability of Keyrings with MasterKeyProviders
WesleyRosenblum Jan 27, 2020
6e473a1
Create individual request types for each AwsCrypto method
WesleyRosenblum Jan 29, 2020
623f6f5
Make EncryptionMaterials, DecryptionMaterials and KeyringTrace immutable
WesleyRosenblum Jan 30, 2020
3af73f0
Rename KmsKeying and related classes to AwsKmsKeyring
WesleyRosenblum Jan 30, 2020
5258475
Create builders for the standard keyrings
WesleyRosenblum Jan 30, 2020
e04c285
Create AwsKmsCmkId type to represent AWS KMS Key Ids
WesleyRosenblum Jan 31, 2020
6396c6c
Add factory methods to Keyring builders
WesleyRosenblum Jan 31, 2020
15c1def
Add comment on not making a defensive copy of plaintext/ciphertext
WesleyRosenblum Jan 31, 2020
6af9b02
Limit ability to create discovery AWS KMS Keyrings to explicit creation
WesleyRosenblum Jan 31, 2020
c182cd5
Add withKeyring to CachingCMM builder
WesleyRosenblum Jan 31, 2020
37d42bb
Fix DecryptRequestTest
WesleyRosenblum Feb 3, 2020
63057f5
Fix Junit 4 assertions in JUnit5 tests
WesleyRosenblum Feb 4, 2020
f415b7f
Renaming StaticKeyring to TestKeyring
WesleyRosenblum Feb 4, 2020
7ec91d6
Adding convenience methods the create builders internally
WesleyRosenblum Feb 6, 2020
876dd5e
Updating wording and adding more Deprecated annotations
WesleyRosenblum Feb 6, 2020
214fabd
Enable AwsKms Client Caching by default to match KmsMasterKeyProvider
WesleyRosenblum Feb 7, 2020
cffe776
Making tests opt-out instead of opt-in and update TestVectorRunner (#…
WesleyRosenblum Feb 7, 2020
8ed8619
Renaming StandardKeyring builder methods and other minors changes
WesleyRosenblum Feb 10, 2020
28aeee2
Fixing test
WesleyRosenblum Feb 11, 2020
ff9dab6
Updating tests to use assertThrows
WesleyRosenblum Feb 11, 2020
12f0c42
Additional example code for Keyrings (#155)
WesleyRosenblum Feb 12, 2020
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
55 changes: 44 additions & 11 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<artifactId>junit-jupiter</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
Expand All @@ -80,6 +80,19 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.2.7</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.code.findbugs</groupId>
Expand Down Expand Up @@ -197,7 +210,7 @@
</profile>

<profile>
<id>full-test-suite</id>
<id>test-suite</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
Expand All @@ -208,30 +221,50 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<includes>
<include>**/AllTestsSuite.java</include>
</includes>
<excludedGroups>ad_hoc</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<!-- This test profile is intended to assist in rapid development; it filters out some of the slower,
more exhaustive tests in the overall test suite to allow for a rapid edit-test cycle. -->
<profile>
<id>fast-tests-only</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<includes>
<include>**/FastTestsOnlySuite.java</include>
</includes>
<excludedGroups>ad_hoc, integration</excludedGroups>
<systemPropertyVariables>
<fastTestsOnly>true</fastTestsOnly>
</systemPropertyVariables>
<!-- Require that this fast suite completes relatively quickly. If you're seeing
this timeout get hit, it's time to pare down tests some more. As a general rule of
thumb, we should avoid any single test taking more than 10s, and try to keep the
number of such slow tests to a minimum. -->
<forkedProcessTimeoutInSeconds>120</forkedProcessTimeoutInSeconds>
</configuration>
</plugin>
</plugins>
</build>
</profile>

<!-- This test profile will run only the integration tests. -->
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<groups>integration</groups>
</configuration>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
import java.util.Map;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
import com.amazonaws.encryptionsdk.AwsCryptoResult;
import com.amazonaws.encryptionsdk.DecryptRequest;
import com.amazonaws.encryptionsdk.EncryptRequest;
import com.amazonaws.encryptionsdk.keyrings.Keyring;
import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings;
import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId;

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

public static void main(final String[] args) {
final String keyArn = args[0];

encryptAndDecrypt(keyArn);
encryptAndDecrypt(AwsKmsCmkId.fromString(args[0]));
}

static void encryptAndDecrypt(final String keyArn) {
static void encryptAndDecrypt(final AwsKmsCmkId keyArn) {
// 1. Instantiate the SDK
final AwsCrypto crypto = new AwsCrypto();

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

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

// 4. Encrypt the data
final CryptoResult<byte[], KmsMasterKey> encryptResult = crypto.encryptData(masterKeyProvider, EXAMPLE_DATA, encryptionContext);
// 4. Encrypt the data with the keyring and encryption context
final AwsCryptoResult<byte[]> encryptResult = crypto.encrypt(
EncryptRequest.builder()
.keyring(keyring)
.encryptionContext(encryptionContext)
.plaintext(EXAMPLE_DATA).build());
final byte[] ciphertext = encryptResult.getResult();

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

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

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

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