Skip to content

Commit e94ee85

Browse files
authored
chore(Examples): Customize KMS Client (#2001)
1 parent 7a0899e commit e94ee85

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ target/
99
/.history
1010
/.DS_Store
1111
/specification_compliance_report.html
12+
.DS_Store
1213

1314
## semantic-release
1415
package-lock.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package com.amazonaws.crypto.examples.keyrings;
2+
3+
import com.amazonaws.encryptionsdk.AwsCrypto;
4+
import com.amazonaws.encryptionsdk.CommitmentPolicy;
5+
import com.amazonaws.encryptionsdk.CryptoResult;
6+
import software.amazon.awssdk.http.SdkHttpClient;
7+
import software.amazon.awssdk.http.apache.ApacheHttpClient;
8+
import software.amazon.awssdk.regions.Region;
9+
import software.amazon.awssdk.services.kms.KmsClient;
10+
import software.amazon.cryptography.materialproviders.IClientSupplier;
11+
import software.amazon.cryptography.materialproviders.IKeyring;
12+
import software.amazon.cryptography.materialproviders.MaterialProviders;
13+
import software.amazon.cryptography.materialproviders.model.CreateAwsKmsKeyringInput;
14+
import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput;
15+
import software.amazon.cryptography.materialproviders.model.GetClientInput;
16+
import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig;
17+
18+
import java.nio.charset.StandardCharsets;
19+
import java.util.Arrays;
20+
import java.util.Collections;
21+
import java.util.Map;
22+
23+
/**
24+
* Encrypts and then decrypts data using an AWS KMS Keyring.
25+
* Demonstrates using a ClientSupplier to customize the KMS SDK Client.
26+
*
27+
* <p>Arguments:
28+
*
29+
* <ol>
30+
* <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master
31+
* key (CMK), see 'Viewing Keys' at
32+
* http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
33+
* </ol>
34+
*/
35+
public class CustomizeSDKClient {
36+
37+
private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);
38+
// See the AWS SDK for Java V2's Guidance for HTTP Client options:
39+
// https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html
40+
private static final SdkHttpClient singletonHttpClient = ApacheHttpClient.builder().build();
41+
42+
public static void main(final String[] args) {
43+
final String keyArn = args[0];
44+
45+
encryptAndDecryptWithKeyring(keyArn);
46+
}
47+
48+
public static class CustomClientSupplier implements IClientSupplier {
49+
50+
@Override
51+
public KmsClient GetClient(GetClientInput getClientInput) {
52+
return KmsClient.builder()
53+
.region(Region.of(getClientInput.region()))
54+
.httpClient(singletonHttpClient)
55+
.build();
56+
}
57+
}
58+
59+
private static final CustomClientSupplier singletonClientSupplier = new CustomClientSupplier();
60+
61+
public static void encryptAndDecryptWithKeyring(final String keyArn) {
62+
// 1. Instantiate the SDK
63+
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
64+
// which enforces that this client only encrypts using committing algorithm suites and enforces
65+
// that this client will only decrypt encrypted messages that were created with a committing
66+
// algorithm suite.
67+
// This is the default commitment policy if you build the client with
68+
// `AwsCrypto.builder().build()`
69+
// or `AwsCrypto.standard()`.
70+
final AwsCrypto crypto =
71+
AwsCrypto.builder()
72+
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
73+
.build();
74+
75+
// 2. Create an AWS KMS Multi-keyring.
76+
// Instead of allowing the KMS MultiKeyring to create the default KMS Client,
77+
// we use the client supplier interface to provide a Client.
78+
final MaterialProviders materialProviders =
79+
MaterialProviders.builder()
80+
.MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
81+
.build();
82+
final CreateAwsKmsMultiKeyringInput multiKeyringInput =
83+
CreateAwsKmsMultiKeyringInput.builder()
84+
.generator(keyArn)
85+
.clientSupplier(singletonClientSupplier)
86+
.build();
87+
final IKeyring kmsMultiKeyring = materialProviders.CreateAwsKmsMultiKeyring(multiKeyringInput);
88+
89+
// 3. Create an encryption context
90+
// Most encrypted data should have an associated encryption context
91+
// to protect integrity. This sample uses placeholder values.
92+
// For more information see:
93+
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
94+
final Map<String, String> encryptionContext =
95+
Collections.singletonMap("ExampleContextKey", "ExampleContextValue");
96+
97+
// 4. Encrypt the data
98+
final CryptoResult<byte[], ?> encryptResult =
99+
crypto.encryptData(kmsMultiKeyring, EXAMPLE_DATA, encryptionContext);
100+
final byte[] ciphertext = encryptResult.getResult();
101+
102+
// 5. Create an AWS KMS
103+
// If we use a normal, plain, KMS Keyring, we have to pass a KMS Client.
104+
// But we could customize this KMS Client to our heart's content.
105+
final CreateAwsKmsKeyringInput keyringInput = CreateAwsKmsKeyringInput.builder()
106+
.kmsClient(KmsClient.builder().httpClient(singletonHttpClient).build())
107+
.kmsKeyId(keyArn)
108+
.build();
109+
110+
final IKeyring kmsKeyring = materialProviders.CreateAwsKmsKeyring(keyringInput);
111+
112+
// 6. Decrypt the data
113+
final CryptoResult<byte[], ?> decryptResult =
114+
crypto.decryptData(
115+
kmsKeyring,
116+
ciphertext,
117+
// Verify that the encryption context in the result contains the
118+
// encryption context supplied to the encryptData method
119+
encryptionContext);
120+
121+
// 6. Verify that the decrypted plaintext matches the original plaintext
122+
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
123+
}
124+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.amazonaws.crypto.examples.keyrings;
2+
3+
import com.amazonaws.encryptionsdk.kms.KMSTestFixtures;
4+
import org.junit.Test;
5+
6+
public class CustomizeSDKClientTest {
7+
@Test
8+
public void testEncryptAndDecrypt() {
9+
BasicEncryptionKeyringExample.encryptAndDecryptWithKeyring(KMSTestFixtures.TEST_KEY_IDS[0]);
10+
}
11+
}

0 commit comments

Comments
 (0)