Skip to content

Commit 756c1e4

Browse files
authored
Merge pull request #23 from juneb/scrub-code-comments
Scrubbed code comments
2 parents eae3056 + 69117d9 commit 756c1e4

File tree

3 files changed

+78
-61
lines changed

3 files changed

+78
-61
lines changed

src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java

+47-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
55
* in compliance with the License. A copy of the License is located at
@@ -36,24 +36,33 @@
3636
* <p>
3737
* Arguments:
3838
* <ol>
39-
* <li>KMS KeyArn
40-
* <li>File Name
39+
* <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master
40+
* key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
41+
*
42+
* <li>Name of file containing plaintext data to encrypt
4143
* </ol>
4244
*
43-
* Some organizations want the ability to decrypt their data even if KMS is unavailable. This
44-
* program demonstrates one possible way of accomplishing this by generating an "Escrow" RSA
45-
* key-pair and using that in addition to the KMS key for encryption. The organization would keep
46-
* the RSA private key someplace secure (such as an offline HSM) and distribute the public key their
47-
* developers. This way all standard use would use KMS for decryption, however the organization
48-
* maintains the ability to decrypt all ciphertexts in a completely offline manner.
45+
* You might use AWS Key Management Service (KMS) for most encryption and decryption operations, but
46+
* still want the option of decrypting your data offline independently of KMS. This sample
47+
* demonstrates one way to do this.
48+
*
49+
* The sample encrypts data under both a KMS customer master key (CMK) and an "escrowed" RSA key pair
50+
* so that either key alone can decrypt it. You might commonly use the KMS CMK for decryption. However,
51+
* at any time, you can use the private RSA key to decrypt the ciphertext independent of KMS.
52+
*
53+
* This sample uses the JCEMasterKey class to generate a RSA public-private key pair
54+
* and saves the key pair in memory. In practice, you would store the private key in a secure offline
55+
* location, such as an offline HSM, and distribute the public key to your development team.
56+
*
4957
*/
5058
public class EscrowedEncryptExample {
5159
private static PublicKey publicEscrowKey;
5260
private static PrivateKey privateEscrowKey;
5361

5462
public static void main(final String[] args) throws Exception {
55-
// In the real world, the public key would be distributed by the organization.
56-
// For this demo, we'll just generate a new random one each time.
63+
// This sample generates a new random key for each operation.
64+
// In practice, you would distribute the public key and save the private key in secure
65+
// storage.
5766
generateEscrowKeyPair();
5867

5968
final String kmsArn = args[0];
@@ -66,23 +75,25 @@ public static void main(final String[] args) throws Exception {
6675
}
6776

6877
private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception {
69-
// Standard user encrypting to both KMS and the escrow public key
78+
// Encrypt with the KMS CMK and the escrowed public key
7079
// 1. Instantiate the SDK
7180
final AwsCrypto crypto = new AwsCrypto();
7281

73-
// 2. Instantiate the providers
82+
// 2. Instantiate a KMS master key provider
7483
final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn);
75-
// Note that the standard user does not have access to the private escrow
76-
// key and so simply passes in "null"
84+
85+
// 3. Instantiate a JCE master key provider
86+
// Because the user does not have access to the private escrow key,
87+
// they pass in "null" for the private key parameter.
7788
final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow",
7889
"RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
7990

80-
// 3. Combine the providers into a single one
91+
// 4. Combine the providers into a single master key provider
8192
final MasterKeyProvider<?> provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub);
8293

83-
// 4. Encrypt the file
84-
// To simplify the code, we'll be omitted Encryption Context this time. Production code
85-
// should always use Encryption Context. Please see the other examples for more information.
94+
// 5. Encrypt the file
95+
// To simplify the code, we omit the encryption context. Production code should always
96+
// use an encryption context. For an example, see the other SDK samples.
8697
final FileInputStream in = new FileInputStream(fileName);
8798
final FileOutputStream out = new FileOutputStream(fileName + ".encrypted");
8899
final CryptoOutputStream<?> encryptingStream = crypto.createEncryptingStream(provider, out);
@@ -93,25 +104,27 @@ private static void standardEncrypt(final String kmsArn, final String fileName)
93104
}
94105

95106
private static void standardDecrypt(final String kmsArn, final String fileName) throws Exception {
96-
// A standard user decrypts the file. They can just use the same provider from before
97-
// or could use a provider just referring to the KMS key. It doesn't matter.
107+
// Decrypt with the KMS CMK and the escrow public key. You can use a combined provider,
108+
// as shown here, or just the KMS master key provider.
98109

99110
// 1. Instantiate the SDK
100111
final AwsCrypto crypto = new AwsCrypto();
101112

102-
// 2. Instantiate the providers
113+
// 2. Instantiate a KMS master key provider
103114
final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn);
104-
// Note that the standard user does not have access to the private escrow
105-
// key and so simply passes in "null"
115+
116+
// 3. Instantiate a JCE master key provider
117+
// Because the user does not have access to the private
118+
// escrow key, they pass in "null" for the private key parameter.
106119
final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow",
107120
"RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
108121

109-
// 3. Combine the providers into a single one
122+
// 4. Combine the providers into a single master key provider
110123
final MasterKeyProvider<?> provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub);
111124

112-
// 4. Decrypt the file
113-
// To simplify the code, we'll be omitted Encryption Context this time. Production code
114-
// should always use Encryption Context. Please see the other examples for more information.
125+
// 5. Decrypt the file
126+
// To simplify the code, we omit the encryption context. Production code should always
127+
// use an encryption context. For an example, see the other SDK samples.
115128
final FileInputStream in = new FileInputStream(fileName + ".encrypted");
116129
final FileOutputStream out = new FileOutputStream(fileName + ".decrypted");
117130
final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(provider, out);
@@ -121,19 +134,20 @@ private static void standardDecrypt(final String kmsArn, final String fileName)
121134
}
122135

123136
private static void escrowDecrypt(final String fileName) throws Exception {
124-
// The organization can decrypt using just the private escrow key with no calls to KMS
137+
// You can decrypt the stream using only the private key.
138+
// This method does not call KMS.
125139

126140
// 1. Instantiate the SDK
127141
final AwsCrypto crypto = new AwsCrypto();
128142

129-
// 2. Instantiate the provider
130-
// Note that the organization does have access to the private escrow key and can use it.
143+
// 2. Instantiate a JCE master key provider
144+
// This method call uses the escrowed private key, not null
131145
final JceMasterKey escrowPriv = JceMasterKey.getInstance(publicEscrowKey, privateEscrowKey, "Escrow", "Escrow",
132146
"RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
133147

134148
// 3. Decrypt the file
135-
// To simplify the code, we'll be omitted Encryption Context this time. Production code
136-
// should always use Encryption Context. Please see the other examples for more information.
149+
// To simplify the code, we omit the encryption context. Production code should always
150+
// use an encryption context. For an example, see the other SDK samples.
137151
final FileInputStream in = new FileInputStream(fileName + ".encrypted");
138152
final FileOutputStream out = new FileOutputStream(fileName + ".deescrowed");
139153
final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(escrowPriv, out);

src/examples/java/com/amazonaws/crypto/examples/FileStreamingExample.java

+18-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
55
* in compliance with the License. A copy of the License is located at
@@ -32,15 +32,15 @@
3232
/**
3333
* <p>
3434
* Encrypts and then decrypts a file under a random key.
35-
*
35+
*
3636
* <p>
3737
* Arguments:
3838
* <ol>
39-
* <li>fileName
39+
* <li>Name of file containing plaintext data to encrypt
4040
* </ol>
41-
*
41+
*
4242
* <p>
43-
* This program demonstrates using a normal java {@link SecretKey} object as a {@link MasterKey} to
43+
* This program demonstrates using a standard Java {@link SecretKey} object as a {@link MasterKey} to
4444
* encrypt and decrypt streaming data.
4545
*/
4646
public class FileStreamingExample {
@@ -49,22 +49,21 @@ public class FileStreamingExample {
4949
public static void main(String[] args) throws IOException {
5050
srcFile = args[0];
5151

52-
// In this example, we'll pretend that we loaded this key from
53-
// some existing store but actually just generate a random one
52+
// In this example, we generate a random key. In practice,
53+
// you would get a key from an existing store
5454
SecretKey cryptoKey = retrieveEncryptionKey();
5555

56-
// Convert key into a provider. We'll use AES GCM because it is
57-
// a good secure algorithm.
56+
// Create a JCE master key provider using the random key and an AES-GCM encryption algorithm
5857
JceMasterKey masterKey = JceMasterKey.getInstance(cryptoKey, "Example", "RandomKey", "AES/GCM/NoPadding");
5958

60-
// Instantiate the SDKs
59+
// Instantiate the SDK
6160
AwsCrypto crypto = new AwsCrypto();
6261

63-
// Create the encryption context to identify this ciphertext
62+
// Create an encryption context to identify this ciphertext
6463
Map<String, String> context = Collections.singletonMap("Example", "FileStreaming");
6564

66-
// The file might be *really* big, so we don't want
67-
// to load it all into memory. Streaming is necessary.
65+
// Because the file might be to large to load into memory, we stream the data, instead of
66+
//loading it all at once.
6867
FileInputStream in = new FileInputStream(srcFile);
6968
CryptoInputStream<JceMasterKey> encryptingStream = crypto.createEncryptingStream(masterKey, in, context);
7069

@@ -73,29 +72,29 @@ public static void main(String[] args) throws IOException {
7372
encryptingStream.close();
7473
out.close();
7574

76-
// Let's decrypt the file now, remembering to check the encryption context
75+
// Decrypt the file. Verify the encryption context before returning the plaintext.
7776
in = new FileInputStream(srcFile + ".encrypted");
7877
CryptoInputStream<JceMasterKey> decryptingStream = crypto.createDecryptingStream(masterKey, in);
79-
// Does it have the right encryption context?
78+
// Does it contain the expected encryption context?
8079
if (!"FileStreaming".equals(decryptingStream.getCryptoResult().getEncryptionContext().get("Example"))) {
8180
throw new IllegalStateException("Bad encryption context");
8281
}
8382

84-
// Finally, actually write out the data
83+
// Return the plaintext data
8584
out = new FileOutputStream(srcFile + ".decrypted");
8685
IOUtils.copy(decryptingStream, out);
8786
decryptingStream.close();
8887
out.close();
8988
}
9089

9190
/**
92-
* In the real world, this key will need to be persisted somewhere. For this demo we'll generate
93-
* a new random one each time.
91+
* In practice, this key would be saved in a secure location.
92+
* For this demo, we generate a new random key for each operation.
9493
*/
9594
private static SecretKey retrieveEncryptionKey() {
9695
SecureRandom rnd = new SecureRandom();
9796
byte[] rawKey = new byte[16]; // 128 bits
9897
rnd.nextBytes(rawKey);
9998
return new SecretKeySpec(rawKey, "AES");
10099
}
101-
}
100+
}

src/examples/java/com/amazonaws/crypto/examples/StringExample.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except
55
* in compliance with the License. A copy of the License is located at
@@ -28,7 +28,8 @@
2828
* <p>
2929
* Arguments:
3030
* <ol>
31-
* <li>KMS Key Arn
31+
* <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master
32+
* key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
3233
* <li>String to encrypt
3334
* </ol>
3435
*/
@@ -48,8 +49,8 @@ public static void main(final String[] args) {
4849

4950
// Encrypt the data
5051
//
51-
// Most encrypted data should have associated encryption context
52-
// to protect integrity. Here, we'll just use a placeholder value.
52+
// Most encrypted data should have an associated encryption context
53+
// to protect integrity. This sample uses placeholder values.
5354
//
5455
// For more information see:
5556
// blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
@@ -60,21 +61,24 @@ public static void main(final String[] args) {
6061

6162
// Decrypt the data
6263
final CryptoResult<String, KmsMasterKey> decryptResult = crypto.decryptString(prov, ciphertext);
63-
// We need to check the encryption context (and ideally key) to ensure that
64-
// this was the ciphertext we expected
64+
65+
// Before returning the plaintext, verify that the customer master key that
66+
// was used in the encryption operation was the one supplied to the master key provider.
6567
if (!decryptResult.getMasterKeyIds().get(0).equals(keyArn)) {
6668
throw new IllegalStateException("Wrong key id!");
6769
}
6870

69-
// The SDK may add information to the encryption context, so we check to ensure
70-
// that all of our values are present
71+
// Also, verify that the encryption context in the result contains the
72+
// encryption context supplied to the encryptString method. Because the
73+
// SDK can add values to the encryption context, don't require that
74+
// the entire context matches.
7175
for (final Map.Entry<String, String> e : context.entrySet()) {
7276
if (!e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey()))) {
7377
throw new IllegalStateException("Wrong Encryption Context!");
7478
}
7579
}
7680

77-
// Now that we know we have the correct data, we can output it.
81+
// Now we can return the plaintext data
7882
System.out.println("Decrypted: " + decryptResult.getResult());
7983
}
8084
}

0 commit comments

Comments
 (0)