-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathRawAes.java
101 lines (88 loc) · 4.42 KB
/
RawAes.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
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package com.amazonaws.crypto.examples.keyring.rawaes;
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 javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* This examples shows how to configure and use a raw AES keyring.
* <p>
* https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring
* <p>
* In this example, we use the one-step encrypt and decrypt APIs.
*/
public class RawAes {
/**
* Demonstrate an encrypt/decrypt cycle using a raw AES keyring.
*
* @param sourcePlaintext Plaintext to encrypt
*/
public static void run(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");
// Generate an AES key to use with your keyring.
//
// In practice, you should get this key from a secure key management system such as an HSM.
SecureRandom rnd = new SecureRandom();
byte[] rawKey = new byte[32]; // 256 bits
rnd.nextBytes(rawKey);
SecretKey key = new SecretKeySpec(rawKey, "AES");
// Create the keyring that determines how your data keys are protected.
final Keyring keyring = StandardKeyrings.rawAesBuilder()
// The key namespace and key name are defined by you
// and are used by the raw AES keyring
// to determine whether it should attempt to decrypt
// an encrypted data key.
//
// https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring
.keyNamespace("some managed raw keys")
.keyName("my AES wrapping key")
.wrappingKey(key)
.build();
// Encrypt your plaintext data.
final AwsCryptoResult<byte[]> encryptResult = awsEncryptionSdk.encrypt(
EncryptRequest.builder()
.keyring(keyring)
.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 same keyring you used on encrypt.
//
// You do not need to specify the encryption context on decrypt because
// the header of the encrypted message includes the encryption context.
final AwsCryptoResult<byte[]> decryptResult = awsEncryptionSdk.decrypt(
DecryptRequest.builder()
.keyring(keyring)
.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));
});
}
}