-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathDiscoveryDecrypt.java
102 lines (89 loc) · 4.66 KB
/
DiscoveryDecrypt.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package com.amazonaws.crypto.examples.keyring.awskms;
import com.amazonaws.encryptionsdk.AwsCrypto;
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;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* When you give the KMS keyring specific key IDs it will use those CMKs and nothing else.
* This is true both on encrypt and on decrypt.
* However, sometimes you need more flexibility on decrypt,
* especially if you might not know beforehand which CMK was used to encrypt a message.
* To address this need, you can use a KMS discovery keyring.
* The KMS discovery keyring will do nothing on encrypt
* but will attempt to decrypt *any* data keys that were encrypted under a KMS CMK.
* <p>
* This example shows how to configure and use a KMS discovery keyring.
* <p>
* https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring
* <p>
* For an example of how to use the KMS keyring with CMKs in multiple regions,
* see the {@link MultipleRegions} example.
* <p>
* For examples of how to use the KMS keyring with custom client configurations,
* see the {@link CustomClientSupplier}
* and {@link CustomKmsClientConfig} examples.
* <p>
* For examples of how to use the KMS discovery keyring on decrypt,
* see the {@link DiscoveryDecryptInRegionOnly},
* and {@link DiscoveryDecryptWithPreferredRegions} examples.
*/
public class DiscoveryDecrypt {
/**
* Demonstrate configuring a KMS discovery keyring for decryption.
*
* @param awsKmsCmk The ARN of an AWS KMS CMK that protects data keys
* @param sourcePlaintext Plaintext to encrypt
*/
public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) {
// Instantiate the AWS Encryption SDK.
final AwsCrypto awsEncryptionSdk = new AwsCrypto();
// Prepare your encryption context.
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context
final Map<String, String> encryptionContext = new HashMap<>();
encryptionContext.put("encryption", "context");
encryptionContext.put("is not", "secret");
encryptionContext.put("but adds", "useful metadata");
encryptionContext.put("that can help you", "be confident that");
encryptionContext.put("the data you are handling", "is what you think it is");
// Create the keyring that determines how your data keys are protected.
final Keyring encryptKeyring = StandardKeyrings.awsKms(awsKmsCmk);
// Create the KMS discovery keyring that we will use on decrypt.
final Keyring decryptKeyring = StandardKeyrings.awsKmsDiscoveryBuilder().build();
// Encrypt your plaintext data.
final AwsCryptoResult<byte[]> encryptResult = awsEncryptionSdk.encrypt(
EncryptRequest.builder()
.keyring(encryptKeyring)
.encryptionContext(encryptionContext)
.plaintext(sourcePlaintext).build());
final byte[] ciphertext = encryptResult.getResult();
// Demonstrate that the ciphertext and plaintext are different.
assert !Arrays.equals(ciphertext, sourcePlaintext);
// Decrypt your encrypted data using the KMS discovery keyring.
//
// We do not need to specify the encryption context on decrypt
// because the header message includes the encryption context.
final AwsCryptoResult<byte[]> decryptResult = awsEncryptionSdk.decrypt(
DecryptRequest.builder()
.keyring(decryptKeyring)
.ciphertext(ciphertext).build());
final byte[] decrypted = decryptResult.getResult();
// Demonstrate that the decrypted plaintext is identical to the original plaintext.
assert Arrays.equals(decrypted, sourcePlaintext);
// Verify that the encryption context used in the decrypt operation includes
// the encryption context that you specified when encrypting.
// The AWS Encryption SDK can add pairs, so don't require an exact match.
//
// In production, always use a meaningful encryption context.
encryptionContext.forEach((k, v) -> {
assert v.equals(decryptResult.getEncryptionContext().get(k));
});
}
}