Skip to content

Commit 099db96

Browse files
committed
chore(Java): New KeyStore KMS Configuration Examples
1 parent a70a569 commit 099db96

21 files changed

+607
-127
lines changed

Examples/runtimes/java/DynamoDbEncryption/README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ Overview:
99
├── src
1010
│ ├── main/java/software/amazon/cryptography/examples: Examples source
1111
│ │ ├── BasicPutGetExample: Example using AWS DB ESDK to Put and Get an encrypted item from DynamoDB
12-
│ │ ├── CreateKeyStoreTableExample: Example creating a Keystore DynamoDB table for use with a hierarchical keyring
13-
│ │ ├── CreateKeyStoreKeyExample: Example creating a branch key in a Keystore DynamoDB table
1412
│ │ ├── clientsupplier: Examples using a custom KMS ClientSupplier
1513
│ │ ├── enhanced: Examples using the DynamoDbEnhancedClient
14+
│ │ ├── hierarchy: Examples using the Hierarchy Keyring and Key Store to reduce calls to KMS
1615
│ │ ├── itemencryptor: Examples using the DynamoDbItemEncryptor
1716
│ │ ├── keyring: Examples creating and using different keyrings
1817
│ │ └── searchableencryption: Examples demonstrating searchable encryption configuration and usage

Examples/runtimes/java/DynamoDbEncryption/build.gradle.kts

+9-1
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,17 @@ dependencies {
7777
implementation("software.amazon.awssdk:dynamodb-enhanced")
7878
implementation("software.amazon.awssdk:kms")
7979
implementation("software.amazon.awssdk:sts")
80-
80+
implementation("software.amazon.awssdk:apache-client:2.19.0")
8181
implementation("org.bouncycastle:bcprov-jdk18on:1.72")
8282

83+
// https://mvnrepository.com/artifact/org.projectlombok/lombok
84+
implementation("org.projectlombok:lombok:1.18.30")
85+
annotationProcessor("org.projectlombok:lombok:1.18.30")
86+
// https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305
87+
implementation("com.google.code.findbugs:jsr305:3.0.2")
88+
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
89+
implementation("org.apache.commons:commons-lang3:3.14.0")
90+
8391
// https://mvnrepository.com/artifact/org.testng/testng
8492
testImplementation("org.testng:testng:7.5")
8593
}

Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/CreateKeyStoreKeyExample.java

-63
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package software.amazon.cryptography.examples;
2+
3+
import javax.annotation.Nonnull;
4+
5+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
6+
import software.amazon.awssdk.http.SdkHttpClient;
7+
import software.amazon.awssdk.regions.Region;
8+
import software.amazon.awssdk.services.sts.StsClient;
9+
import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider;
10+
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
11+
12+
13+
public class CredentialUtils {
14+
public static StsAssumeRoleCredentialsProvider credsForRole(
15+
@Nonnull String roleArn,
16+
@Nonnull String roleSessionName,
17+
@Nonnull Region region,
18+
@Nonnull SdkHttpClient httpClient,
19+
@Nonnull AwsCredentialsProvider creds
20+
) {
21+
StsAssumeRoleCredentialsProvider provider = StsAssumeRoleCredentialsProvider.builder()
22+
.stsClient(StsClient.builder().httpClient(httpClient).region(region).credentialsProvider(creds).build())
23+
.refreshRequest(AssumeRoleRequest.builder()
24+
.roleArn(roleArn)
25+
.roleSessionName(roleSessionName)
26+
.durationSeconds(900) // 15 minutes by 60 seconds
27+
.build()).build();
28+
// Force credential resolution.
29+
// If the host does not have permission to use these credentials,
30+
// we want to fail early.
31+
// This may not be appropriate in a production environment,
32+
// as it is "greedy initialization".
33+
provider.resolveCredentials();
34+
return provider;
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package software.amazon.cryptography.examples;
2+
3+
import org.apache.commons.lang3.StringUtils;
4+
5+
import javax.annotation.Nonnull;
6+
import javax.annotation.Nullable;
7+
8+
public class EnvUtils {
9+
@Nonnull
10+
public static String envOrDefault(@Nonnull String key, @Nonnull String _default) {
11+
@Nullable String maybe = System.getenv(key);
12+
if (StringUtils.isEmpty(maybe)) {
13+
return _default;
14+
}
15+
return maybe;
16+
}
17+
18+
@Nonnull
19+
public static String envOrFail(@Nonnull String key) {
20+
@Nullable String maybe = System.getenv(key);
21+
if (StringUtils.isEmpty(maybe)) {
22+
throw new RuntimeException(String.format("Env had no key: %s", key));
23+
}
24+
return maybe;
25+
}
26+
}
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package software.amazon.cryptography.examples.hierarchy.controlPlane;
2+
3+
import java.time.Duration;
4+
5+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
6+
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
7+
import software.amazon.awssdk.http.SdkHttpClient;
8+
import software.amazon.awssdk.http.apache.ApacheHttpClient;
9+
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
10+
import software.amazon.cryptography.keystore.KeyStore;
11+
import software.amazon.cryptography.keystore.model.CreateKeyInput;
12+
13+
/*
14+
The Hierarchical Keyring Example and Searchable Encryption Examples
15+
rely on the existence of a DDB-backed key store with pre-existing
16+
branch key material or beacon key material.
17+
18+
See the "Create KeyStore Table Example" for how to first set up
19+
the DDB Table that will back this KeyStore.
20+
21+
This example demonstrates configuring a KeyStore and then
22+
using a helper method to create a branch key and beacon key
23+
that share the same Id, then return that Id.
24+
We will always create a new beacon key alongside a new branch key,
25+
even if you are not using searchable encryption.
26+
27+
This key creation should occur within your control plane.
28+
*/
29+
@SuppressWarnings("UnnecessaryLocalVariable")
30+
public class CreateBranchKeyExample {
31+
public static String KeyStoreCreateKey(
32+
String keyStoreTableName,
33+
String logicalKeyStoreName,
34+
String kmsKeyArn,
35+
DynamoDbClient keystoreAdminDDBClient,
36+
SdkHttpClient kmsHTTPClient,
37+
AwsCredentialsProvider kmsCredentials
38+
) {
39+
final StrictKeyStoreFactory factory = new StrictKeyStoreFactory(
40+
kmsHTTPClient,
41+
keystoreAdminDDBClient,
42+
keyStoreTableName,
43+
logicalKeyStoreName);
44+
// 1. Configure your KeyStore resource.
45+
// See StrictKeyStoreFactory.
46+
// Only Strict KeyStores can Create or Version Branch Keys
47+
final KeyStore keystore = factory.getKeyStore(kmsKeyArn, kmsCredentials);
48+
49+
// 2. Create a new branch key and beacon key in our KeyStore.
50+
// Both the branch key and the beacon key will share an Id.
51+
// This creation is eventually consistent.
52+
// This MUST be done before data can be encrypted or decrypted with this Branch Key.
53+
// Ideally, for the Multi-Tenant use case,
54+
// Branch Key Creation is executed when a tenant
55+
// onboards to the service or application.
56+
final String branchKeyId = keystore.CreateKey(CreateKeyInput.builder().build()).branchKeyIdentifier();
57+
58+
return branchKeyId;
59+
}
60+
61+
public static void main(final String[] args) {
62+
if (args.length <= 1) {
63+
throw new IllegalArgumentException("To run this example, include the keyStoreTableName, logicalKeyStoreName, and kmsKeyArn in args");
64+
}
65+
final String keyStoreTableName = args[0];
66+
final String logicalKeyStoreName = args[1];
67+
final String kmsKeyArn = args[2];
68+
// It is more efficient to re-use these than create unique ones for DDB & KMS.
69+
final AwsCredentialsProvider defaultCreds = DefaultCredentialsProvider.create();
70+
final SdkHttpClient httpClient = ApacheHttpClient.builder()
71+
.connectionTimeToLive(Duration.ofSeconds(5)).build();
72+
final DynamoDbClient keystoreAdminDDBClient = DynamoDbClient.builder()
73+
.httpClient(httpClient)
74+
.credentialsProvider(defaultCreds)
75+
.build();
76+
KeyStoreCreateKey(keyStoreTableName, logicalKeyStoreName, kmsKeyArn, keystoreAdminDDBClient, httpClient, defaultCreds);
77+
}
78+
}

0 commit comments

Comments
 (0)