From 81091ae79cca7c0fbcb7b2a262903abb173da522 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Fri, 20 Mar 2020 14:18:40 -0700 Subject: [PATCH 1/6] Adding new examples and example test runner to follow the format set in https://github.com/aws/aws-encryption-sdk-python/pull/219 --- src/examples/README.md | 88 +++++++++ .../examples/BasicEncryptionExample.java | 97 ---------- .../examples/EscrowedEncryptExample.java | 158 ---------------- .../examples/FileStreamingDefaults.java | 144 +++++++++++++++ .../crypto/examples/FileStreamingExample.java | 150 --------------- .../examples/InMemoryStreamingDefaults.java | 113 ++++++++++++ .../crypto/examples/OneStepDefaults.java | 93 ++++++++++ .../crypto/examples/OneStepUnsigned.java | 107 +++++++++++ .../crypto/examples/RawAesKeyringExample.java | 100 ---------- .../examples/RawRsaKeyringDecryptExample.java | 57 ------ .../examples/RawRsaKeyringEncryptExample.java | 64 ------- .../keyring/awskms/CustomClientSupplier.java | 149 +++++++++++++++ .../keyring/awskms/CustomKmsClientConfig.java | 128 +++++++++++++ .../keyring/awskms/DiscoveryDecrypt.java | 112 ++++++++++++ .../awskms/DiscoveryDecryptInRegionOnly.java | 128 +++++++++++++ .../DiscoveryDecryptWithPreferredRegions.java | 144 +++++++++++++++ .../keyring/awskms/MultipleRegions.java | 132 ++++++++++++++ .../examples/keyring/awskms/SingleCmk.java | 102 +++++++++++ .../keyring/multi/AwsKmsWithEscrow.java | 157 ++++++++++++++++ .../examples/keyring/rawaes/RawAes.java | 111 +++++++++++ .../rawrsa/PublicPrivateKeySeparate.java | 152 ++++++++++++++++ .../examples/keyring/rawrsa/RawRsa.java | 117 ++++++++++++ .../legacy/BasicEncryptionExample.java | 91 +++++++++ .../legacy/EscrowedEncryptExample.java | 172 ++++++++++++++++++ .../examples/legacy/FileStreamingExample.java | 103 +++++++++++ .../LambdaDecryptAndWriteExample.java | 4 +- .../MultiRegionRecordPusherExample.java | 4 +- .../SimpleDataKeyCachingExample.java | 2 +- .../examples/BasicEncryptionExampleTest.java | 29 --- .../examples/EscrowedEncryptExampleTest.java | 31 ---- .../crypto/examples/ExamplesTest.java | 129 +++++++++++++ .../examples/FileStreamingExampleTest.java | 44 ----- .../examples/RawAesKeyringExampleTest.java | 24 --- .../RawRsaKeyringDecryptExampleTest.java | 37 ---- .../RawRsaKeyringEncryptExampleTest.java | 55 ------ .../SimpleDataKeyCachingExampleTest.java | 29 --- 36 files changed, 2477 insertions(+), 880 deletions(-) create mode 100644 src/examples/README.md delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/FileStreamingExample.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/RawAesKeyringExample.java delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExample.java delete mode 100644 src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExample.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java create mode 100644 src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java rename src/examples/java/com/amazonaws/crypto/examples/{datakeycaching => legacy}/LambdaDecryptAndWriteExample.java (97%) rename src/examples/java/com/amazonaws/crypto/examples/{datakeycaching => legacy}/MultiRegionRecordPusherExample.java (97%) rename src/examples/java/com/amazonaws/crypto/examples/{datakeycaching => legacy}/SimpleDataKeyCachingExample.java (98%) delete mode 100644 src/test/java/com/amazonaws/crypto/examples/BasicEncryptionExampleTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/EscrowedEncryptExampleTest.java create mode 100644 src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/FileStreamingExampleTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/RawAesKeyringExampleTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExampleTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExampleTest.java delete mode 100644 src/test/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExampleTest.java diff --git a/src/examples/README.md b/src/examples/README.md new file mode 100644 index 000000000..ed94c6761 --- /dev/null +++ b/src/examples/README.md @@ -0,0 +1,88 @@ +# AWS Encryption SDK Examples + +This section features examples that show you +how to use the AWS Encryption SDK. +We demonstrate how to use the encryption and decryption APIs +and how to set up some common configuration patterns. + +## APIs + +The AWS Encryption SDK provides two high-level APIs: +one-step APIs that process the entire operation in memory +and streaming APIs. + +You can find examples that demonstrate these APIs +in the [`examples`](./java/com/amazonaws/crypto/examples) directory. + +## Configuration + +To use the library APIs, +you need to describe how you want the library to protect your data keys. +You can do this using +[keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers), +or using [master key providers](#master-key-providers). +These examples will show you how. + +### Keyrings + +Keyrings are the most common way for you to configure the AWS Encryption SDK. +They determine how the AWS Encryption SDK protects your data. +You can find these examples in ['examples/keyring`](./java/com/amazonaws/crypto/examples/keyring). + +### Cryptographic Materials Managers + +Keyrings define how your data keys are protected, +but there is more going on here than just protecting data keys. + +Cryptographic materials managers give you higher-level controls +over how the AWS Encryption SDK protects your data. +This can include things like +enforcing the use of certain algorithm suites or encryption context settings, +reusing data keys across messages, +or changing how you interact with keyrings. +You can find these examples in +[`examples/crypto_materials_manager`](./java/com/amazonaws/crypto/examples/cryptomaterialsmanager). + +### Master Key Providers + +Before there were keyrings, there were master key providers. +Master key providers were the original configuration structure +that we provided for defining how you want to protect your data keys. +Keyrings provide a simpler experience and often more powerful configuration options, +but if you need to use master key providers, +need help migrating from master key providers to keyrings, +or simply want to see the difference between these configuration experiences, +you can find these examples in [`examples/masterkeyprovider`](./java/com/amazonaws/crypto/examples/masterkeyprovider). + +## Legacy + +This section includes older examples, +including examples of using master keys and master key providers. +You can use them as a reference, +but we recommend looking at the newer examples, which explain the preferred ways of using this library. +You can find these examples in [`examples/legacy`](./java/com/amazonaws/crypto/examples/legacy). + +# Writing Examples + +If you want to contribute a new example, that's awesome! +To make sure that your example is tested in our CI, +please make sure that it meets the following requirements: + +1. The example MUST be a distinct class in the [`examples`](./java/com/amazonaws/crypto/examples) directory. +1. Each example file MUST contain exactly one example. +1. Each example file MUST contain a static method called `run` that runs the example. +1. If your `run` method needs any of the following inputs, + the parameters MUST have the following types: + * `com.amazonaws.encryptionsdk.kms.AwsKmsCmkId` : A single AWS KMS CMK ARN. + * NOTE: You can assume that automatically discovered credentials have + `kms:GenerateDataKey`, `kms:Encrypt`, and `kms:Decrypt` permissions on this CMK. + * `List` : + A list of AWS KMS CMK ARNs to use for encrypting and decrypting data keys. + * NOTE: You can assume that automatically discovered credentials have + `kms:Encrypt` and `kms:Decrypt` permissions on these CMKs. + * `byte[]` : Plaintext data to encrypt. + * `java.io.File` : A path to a file containing plaintext to encrypt. + * NOTE: You can assume that you have write access to the parent directory + and that anything you do in that directory will be cleaned up + by our test runners. +1. Any additional parameters MUST be optional and nullable and not of the same type as the above parameters. diff --git a/src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java b/src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java deleted file mode 100644 index ce1dcca3c..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/BasicEncryptionExample.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -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; - -/** - *

- * Encrypts and then decrypts data using an AWS Key Management Service (AWS KMS) customer master key. - * - *

- * Arguments: - *

    - *
  1. Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master - * key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html - *
- */ -public class BasicEncryptionExample { - - private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); - - public static void main(final String[] args) { - encryptAndDecrypt(AwsKmsCmkId.fromString(args[0])); - } - - static void encryptAndDecrypt(final AwsKmsCmkId keyArn) { - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a KMS keyring. Supply the key ARN for the generator key - // that generates a data key. While using a key ARN is a best practice, - // for encryption operations you can also use an alias name or alias ARN. - final Keyring keyring = StandardKeyrings.awsKms(keyArn); - - // 3. Create an encryption context - // - // Most encrypted data should have an associated encryption context - // to protect integrity. This sample uses placeholder values. - // - // For more information see: - // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management - final Map encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); - - // 4. Encrypt the data with the keyring and encryption context - final AwsCryptoResult encryptResult = crypto.encrypt( - EncryptRequest.builder() - .keyring(keyring) - .encryptionContext(encryptionContext) - .plaintext(EXAMPLE_DATA).build()); - final byte[] ciphertext = encryptResult.getResult(); - - // 5. Decrypt the data. You can use the same keyring to encrypt and decrypt, but for decryption - // the key IDs must be in the key ARN format. - final AwsCryptoResult decryptResult = crypto.decrypt( - DecryptRequest.builder() - .keyring(keyring) - .ciphertext(ciphertext).build()); - - // 6. To verify the CMK that was actually used in the decrypt operation, inspect the keyring trace. - if(!decryptResult.getKeyringTrace().getEntries().get(0).getKeyName().equals(keyArn.toString())) { - throw new IllegalStateException("Wrong key ID!"); - } - - // 7. To verify that the encryption context used to decrypt the data was the encryption context you expected, - // examine the encryption context in the result. This helps to ensure that you decrypted the ciphertext that - // you intended. - // - // When verifying, test that your expected encryption context is a subset of the actual encryption context, - // not an exact match. The Encryption SDK adds the signing key to the encryption context when appropriate. - assert decryptResult.getEncryptionContext().get("ExampleContextKey").equals("ExampleContextValue"); - - // 8. Verify that the decrypted plaintext matches the original plaintext - assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); - } -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java deleted file mode 100644 index bb12f737d..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/EscrowedEncryptExample.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.AwsCrypto; -import com.amazonaws.encryptionsdk.DecryptRequest; -import com.amazonaws.encryptionsdk.EncryptRequest; -import com.amazonaws.encryptionsdk.keyrings.Keyring; -import com.amazonaws.encryptionsdk.keyrings.RawRsaKeyringBuilder.RsaPaddingScheme; -import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; -import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; - -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.util.Arrays; - -/** - *

- * Encrypts data using both KMS and an asymmetric key pair. - * - *

- * Arguments: - *

    - *
  1. Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master - * key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html - *
- * - * You might use AWS Key Management Service (KMS) for most encryption and decryption operations, but - * still want the option of decrypting your data offline independently of KMS. This sample - * demonstrates one way to do this. - * - * The sample encrypts data under both a KMS customer master key (CMK) and an "escrowed" RSA key pair - * so that either key alone can decrypt it. You might commonly use the KMS CMK for decryption. However, - * at any time, you can use the private RSA key to decrypt the ciphertext independent of KMS. - * - * This sample uses a RawRsaKeyring to generate a RSA public-private key pair - * and saves the key pair in memory. In practice, you would store the private key in a secure offline - * location, such as an offline HSM, and distribute the public key to your development team. - * - */ -public class EscrowedEncryptExample { - private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); - - public static void main(final String[] args) throws GeneralSecurityException { - escrowEncryptAndDecrypt(AwsKmsCmkId.fromString(args[0])); - } - - static void escrowEncryptAndDecrypt(AwsKmsCmkId kmsArn) throws GeneralSecurityException { - // This sample generates a new random key for each operation. - // In practice, you would distribute the public key and save the private key in secure storage. - final KeyPair escrowKeyPair = generateEscrowKeyPair(); - - // Encrypt the data under both a KMS Key and an escrowed RSA Key - byte[] encryptedData = standardEncrypt(kmsArn, escrowKeyPair.getPublic()); - - // Decrypt the data using the KMS Key - byte[] standardDecryptedData = standardDecrypt(kmsArn, encryptedData); - - // Decrypt the data using the escrowed RSA Key - byte[] escrowedDecryptedData = escrowDecrypt(encryptedData, escrowKeyPair.getPrivate()); - - // Verify both decrypted data instances are the same as the original plaintext - assert Arrays.equals(standardDecryptedData, EXAMPLE_DATA); - assert Arrays.equals(escrowedDecryptedData, EXAMPLE_DATA); - } - - private static byte[] standardEncrypt(final AwsKmsCmkId kmsArn, final PublicKey publicEscrowKey) { - // Encrypt with the KMS CMK and the escrowed public key - - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a KMS keyring, supplying the keyArn as the generator for generating a data key. - final Keyring kmsKeyring = StandardKeyrings.awsKms(kmsArn); - - // 3. Instantiate a RawRsaKeyring - // Because the user does not have access to the private escrow key, - // they do not provide the private key parameter. - final Keyring rsaKeyring = StandardKeyrings.rawRsaBuilder() - .keyNamespace("Escrow") - .keyName("Escrow") - .publicKey(publicEscrowKey) - .paddingScheme(RsaPaddingScheme.OAEP_SHA512_MGF1) - .build(); - - // 4. Combine the providers into a single MultiKeyring - final Keyring keyring = StandardKeyrings.multi(kmsKeyring, rsaKeyring); - - // 5. Encrypt the data with the keyring. - // To simplify the code, we omit the encryption context. Production code should always - // use an encryption context. For an example, see the other SDK samples. - return crypto.encrypt(EncryptRequest.builder() - .keyring(keyring) - .plaintext(EXAMPLE_DATA).build()) - .getResult(); - } - - private static byte[] standardDecrypt(final AwsKmsCmkId kmsArn, final byte[] cipherText) { - // Decrypt with the KMS CMK - - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a KMS keyring, supplying the keyArn as the generator for generating a data key. - final Keyring kmsKeyring = StandardKeyrings.awsKms(kmsArn); - - // 4. Decrypt the data with the keyring. - // To simplify the code, we omit the encryption context. Production code should always - // use an encryption context. For an example, see the other SDK samples. - return crypto.decrypt(DecryptRequest.builder() - .keyring(kmsKeyring) - .ciphertext(cipherText).build()).getResult(); - } - - private static byte[] escrowDecrypt(final byte[] cipherText, final PrivateKey privateEscrowKey) { - // You can decrypt the stream using only the private key. - // This method does not call KMS. - - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a RawRsaKeyring using the escrowed private key - final Keyring rsaKeyring = StandardKeyrings.rawRsaBuilder() - .keyNamespace("Escrow") - .keyName("Escrow") - .privateKey(privateEscrowKey) - .paddingScheme(RsaPaddingScheme.OAEP_SHA512_MGF1) - .build(); - - // 3. Decrypt the data with the keyring - // To simplify the code, we omit the encryption context. Production code should always - // use an encryption context. For an example, see the other SDK samples. - return crypto.decrypt(DecryptRequest.builder() - .keyring(rsaKeyring) - .ciphertext(cipherText).build()).getResult(); - } - - private static KeyPair generateEscrowKeyPair() throws GeneralSecurityException { - final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); // Escrow keys should be very strong - return kg.generateKeyPair(); - } -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java new file mode 100644 index 000000000..917fe7636 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java @@ -0,0 +1,144 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.AwsCryptoInputStream; +import com.amazonaws.encryptionsdk.AwsCryptoResult; +import com.amazonaws.encryptionsdk.CreateDecryptingInputStreamRequest; +import com.amazonaws.encryptionsdk.CreateEncryptingInputStreamRequest; +import com.amazonaws.encryptionsdk.keyrings.Keyring; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; +import com.amazonaws.util.IOUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * This example shows how to use the streaming encrypt and decrypt APIs when working with files. + *

+ * One benefit of using the streaming API is that + * we can check the encryption context before we start decrypting. + *

+ * In this example, we use an AWS KMS customer master key (CMK), + * but you can use other key management options with the AWS Encryption SDK. + * For examples that demonstrate how to use other key management configurations, + * see the 'keyring' and 'masterkeyprovider' directories. + */ +public class FileStreamingDefaults { + + /** + * Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs with files. + * + * @param awsKmsCmk The ARN of an AWS KMS CMK that protects data keys + * @param sourcePlaintextFile Plaintext file to encrypt + */ + public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFile) throws IOException { + // Instantiate the SDK + final AwsCrypto awsEncryptionSdk = new AwsCrypto(); + + // We assume that you can also write to the directory containing the plaintext file, + // so that is where we will put all of the results. + final File encryptedFile = new File(sourcePlaintextFile.getPath() + ".encrypted"); + final File decryptedFile = new File(sourcePlaintextFile.getPath() + ".decrypted"); + encryptedFile.deleteOnExit(); + decryptedFile.deleteOnExit(); + + // Prepare your encryption context + // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + final Map 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 keyring = StandardKeyrings.awsKms(awsKmsCmk); + + // Create the encrypting input stream with the keyring and encryption context. + // Because the file might be too large to load into memory, + // we stream the data, instead of loading it all at once. + try (final AwsCryptoInputStream encryptingStream = awsEncryptionSdk.createEncryptingInputStream( + CreateEncryptingInputStreamRequest.builder() + .keyring(keyring) + .encryptionContext(encryptionContext) + .inputStream(new FileInputStream(sourcePlaintextFile)).build())) { + + // Copy the encrypted data into the encrypted file. + try (FileOutputStream out = new FileOutputStream(encryptedFile)) { + IOUtils.copy(encryptingStream, out); + } + } + + // Demonstrate that the ciphertext and plaintext are different. + assert !compareFiles(sourcePlaintextFile, encryptedFile); + + // Create the decrypting input stream with the keyring. + try (final AwsCryptoInputStream decryptingStream = awsEncryptionSdk.createDecryptingInputStream( + CreateDecryptingInputStreamRequest.builder() + .keyring(keyring) + .inputStream(new FileInputStream(encryptedFile)).build())) { + + // Check the encryption context before we start decrypting. + // + // 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. + final AwsCryptoResult decryptResult = decryptingStream.getAwsCryptoResult(); + encryptionContext.forEach((k, v) -> { + assert v.equals(decryptResult.getEncryptionContext().get(k)); + }); + + // Copy the plaintext data to a file + try (FileOutputStream out = new FileOutputStream(decryptedFile)) { + IOUtils.copy(decryptingStream, out); + } + } + + // Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert compareFiles(sourcePlaintextFile, decryptedFile); + } + + private static boolean compareFiles(File file1, File file2) throws IOException { + if (file1.length() != file2.length()) { + return false; + } + + try (BufferedReader file1Reader = Files.newBufferedReader(file1.toPath()); + BufferedReader file2Reader = Files.newBufferedReader(file2.toPath())) { + String file1Line; + String file2Line; + + while ((file1Line = file1Reader.readLine()) != null && + (file2Line = file2Reader.readLine()) != null) { + if (!Objects.equals(file1Line, file2Line)) { + return false; + } + } + + return true; + } + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingExample.java b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingExample.java deleted file mode 100644 index 94cd38853..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingExample.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.AwsCrypto; -import com.amazonaws.encryptionsdk.AwsCryptoInputStream; -import com.amazonaws.encryptionsdk.CreateDecryptingInputStreamRequest; -import com.amazonaws.encryptionsdk.CreateEncryptingInputStreamRequest; -import com.amazonaws.encryptionsdk.keyrings.Keyring; -import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; -import com.amazonaws.util.IOUtils; - -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.security.SecureRandom; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; - -/** - *

- * Encrypts and then decrypts a file under a random key. - * - *

- * Arguments: - *

    - *
  1. Name of file containing plaintext data to encrypt - *
- * - *

- * This program demonstrates using a standard Java {@link SecretKey} object in a {@link Keyring} to - * encrypt and decrypt streaming data. - */ -public class FileStreamingExample { - - public static void main(String[] args) throws IOException { - final File srcFile = new File(args[0]); - final File encryptedFile = new File(args[1]); - final File decryptedFile = new File(args[2]); - - encryptAndDecrypt(srcFile, encryptedFile, decryptedFile); - - } - - static void encryptAndDecrypt(final File srcFile, final File encryptedFile, final File decryptedFile) throws IOException { - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Get an encryption key. In this example, we generate a random key. - // In practice, you would get a key from an existing key store. - final SecretKey cryptoKey = generateEncryptKey(); - - // 3. Instantiate a RawAesKeyring using the random key - final Keyring keyring = StandardKeyrings.rawAesBuilder() - .keyNamespace("Example") - .keyName("RandomKey") - .wrappingKey(cryptoKey) - .build(); - - // 4. Create an encryption context - // - // Most encrypted data should have an associated encryption context - // to protect integrity. This sample uses placeholder values. - // - // For more information see: - // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management - final Map encryptionContext = Collections.singletonMap("Example", "FileStreaming"); - - // 5. Create the encrypting input stream with the keyring and encryption context. - // Because the file might be too large to load into memory, - // we stream the data, instead of loading it all at once. - try (final AwsCryptoInputStream encryptingStream = crypto.createEncryptingInputStream( - CreateEncryptingInputStreamRequest.builder() - .keyring(keyring) - .encryptionContext(encryptionContext) - .inputStream(new FileInputStream(srcFile)).build())) { - - // 6. Copy the encrypted data into the encrypted file. - try (FileOutputStream out = new FileOutputStream(encryptedFile)) { - IOUtils.copy(encryptingStream, out); - } - } - - // 7. Create the decrypting input stream with the keyring. - try (final AwsCryptoInputStream decryptingStream = crypto.createDecryptingInputStream( - CreateDecryptingInputStreamRequest.builder() - .keyring(keyring) - .inputStream(new FileInputStream(encryptedFile)).build())) { - - // 8. Verify that the encryption context that was used to decrypt the data is the one that you expect. - // This helps to ensure that the ciphertext that you decrypted was the one that you intended. - // - // When verifying, test that your expected encryption context is a subset of the actual encryption context, - // not an exact match. When appropriate, the Encryption SDK adds the signing key to the encryption context. - assert "FileStreaming".equals(decryptingStream.getAwsCryptoResult().getEncryptionContext().get("Example")); - - // 9. Copy the plaintext data to a file - try (FileOutputStream out = new FileOutputStream(decryptedFile)) { - IOUtils.copy(decryptingStream, out); - } - } - - // 10. Compare the decrypted file to the original - compareFiles(decryptedFile, srcFile); - } - - /** - * In practice, this key would be saved in a secure location. - * In this example, we generate a new random key for each operation. - */ - private static SecretKey generateEncryptKey() { - SecureRandom rnd = new SecureRandom(); - byte[] rawKey = new byte[16]; // 128 bits - rnd.nextBytes(rawKey); - return new SecretKeySpec(rawKey, "AES"); - } - - private static void compareFiles(File file1, File file2) throws IOException { - assert file1.length() == file2.length(); - - try (BufferedReader file1Reader = Files.newBufferedReader(file1.toPath()); - BufferedReader file2Reader = Files.newBufferedReader(file2.toPath())) { - String file1Line; - String file2Line; - - while ((file1Line = file1Reader.readLine()) != null && - (file2Line = file2Reader.readLine()) != null) { - assert Objects.equals(file1Line, file2Line); - } - } - } - -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java new file mode 100644 index 000000000..97dcf91b0 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java @@ -0,0 +1,113 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.AwsCryptoInputStream; +import com.amazonaws.encryptionsdk.AwsCryptoResult; +import com.amazonaws.encryptionsdk.CreateDecryptingInputStreamRequest; +import com.amazonaws.encryptionsdk.CreateEncryptingInputStreamRequest; +import com.amazonaws.encryptionsdk.keyrings.Keyring; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; +import com.amazonaws.util.IOUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * This example shows how to use the streaming encrypt and decrypt APIs on data in memory. + *

+ * One benefit of using the streaming API is that + * we can check the encryption context before we start decrypting. + *

+ * In this example, we use an AWS KMS customer master key (CMK), + * but you can use other key management options with the AWS Encryption SDK. + * For examples that demonstrate how to use other key management configurations, + * see the 'keyring' and 'masterkeyprovider' directories. + */ +public class InMemoryStreamingDefaults { + + /** + * Demonstrate an encrypt/decrypt cycle using the streaming encrypt/decrypt APIs in-memory. + * + * @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) throws IOException { + // Instantiate the 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 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 keyring = StandardKeyrings.awsKms(awsKmsCmk); + + ByteArrayInputStream inputStream = new ByteArrayInputStream(sourcePlaintext); + + // Create the encrypting input stream with the keyring and encryption context. + final AwsCryptoInputStream encryptingStream = awsEncryptionSdk.createEncryptingInputStream( + CreateEncryptingInputStreamRequest.builder() + .keyring(keyring) + .encryptionContext(encryptionContext) + .inputStream(inputStream).build()); + + // Encrypt the plaintext and write the results into the ciphertext. + ByteArrayOutputStream ciphertext = new ByteArrayOutputStream(); + IOUtils.copy(encryptingStream, ciphertext); + + // Demonstrate that the ciphertext and plaintext are different. + assert !Arrays.equals(ciphertext.toByteArray(), sourcePlaintext); + + // Decrypt your encrypted data using the same keyring you used on encrypt. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoInputStream decryptingStream = awsEncryptionSdk.createDecryptingInputStream( + CreateDecryptingInputStreamRequest.builder() + .keyring(keyring) + .inputStream(new ByteArrayInputStream(ciphertext.toByteArray())).build()); + + // Check the encryption context before we start decrypting. + // + // 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. + final AwsCryptoResult decryptResult = decryptingStream.getAwsCryptoResult(); + encryptionContext.forEach((k, v) -> { + assert v.equals(decryptResult.getEncryptionContext().get(k)); + }); + + // Now that we are more confident that we will decrypt the right message, + // we can start decrypting. + ByteArrayOutputStream decrypted = new ByteArrayOutputStream(); + IOUtils.copy(decryptingStream, decrypted); + + // Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert Arrays.equals(decrypted.toByteArray(), sourcePlaintext); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java new file mode 100644 index 000000000..cd3b5b5c1 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java @@ -0,0 +1,93 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples; + +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; + +/** + * This example shows how to use the one-step encrypt and decrypt APIs. + *

+ * In this example, we use an AWS KMS customer master key (CMK), + * but you can use other key management options with the AWS Encryption SDK. + * For examples that demonstrate how to use other key management configurations, + * see the 'keyring' and 'masterkeyprovider' directories. + */ +public class OneStepDefaults { + + /** + * Demonstrate an encrypt/decrypt cycle using the one-step encrypt/decrypt APIs. + * + * @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 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 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 keyring = StandardKeyrings.awsKms(awsKmsCmk); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java new file mode 100644 index 000000000..86f921c0b --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java @@ -0,0 +1,107 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.AwsCryptoResult; +import com.amazonaws.encryptionsdk.CryptoAlgorithm; +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; + +/** + * This example shows how to specify an algorithm suite + * when using the one-step encrypt and decrypt APIs. + *

+ * In this example, we use an AWS KMS customer master key (CMK), + * but you can use other key management options with the AWS Encryption SDK. + * For examples that demonstrate how to use other key management configurations, + * see the 'keyring' and 'masterkeyprovider' directories. + *

+ * The default algorithm suite includes a message-level signature + * that protects you from an attacker who has *decrypt* but not *encrypt* capability + * for a wrapping key that you used when encrypting a message + * under multiple wrapping keys. + *

+ * However, if all of your readers and writers have the same permissions, + * then this additional protection does not always add value. + * This example shows you how to select another algorithm suite + * that has all of the other properties of the default suite + * but does not include a message-level signature. + */ +public class OneStepUnsigned { + + /** + * Demonstrate requesting a specific algorithm suite through the one-step encrypt/decrypt APIs. + * + * @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 SDK and specify the algorithm suite that we want to use. + final AwsCrypto awsEncryptionSdk = new AwsCrypto(); + awsEncryptionSdk.setEncryptionAlgorithm(CryptoAlgorithm.ALG_AES_256_GCM_IV12_TAG16_HKDF_SHA256); + + // Prepare your encryption context + // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + final Map 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 keyring = StandardKeyrings.awsKms(awsKmsCmk); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/RawAesKeyringExample.java b/src/examples/java/com/amazonaws/crypto/examples/RawAesKeyringExample.java deleted file mode 100644 index 9af19ca54..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/RawAesKeyringExample.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -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.KeyGenerator; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -/** - *

- * Encrypts and then decrypts data using the Raw AES keyring. - */ -public class RawAesKeyringExample { - - private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); - - public static void main(final String[] args) { - encryptAndDecrypt(); - } - - static void encryptAndDecrypt() { - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Get an encryption key. In this example, we generate a random key. - // In practice, you would get a key from an existing key store - final SecretKey cryptoKey = generateEncryptKey(); - - // 3. Instantiate a Raw AES keyring with the encryption key - final Keyring keyring = StandardKeyrings.rawAesBuilder() - .keyNamespace("ExampleKeyNamespace") - .keyName("ExampleKeyName") - .wrappingKey(cryptoKey).build(); - - // 4. Create an encryption context - // - // Most encrypted data should have an associated encryption context - // to protect integrity. This sample uses placeholder values. - // - // For more information see: - // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management - final Map encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); - - // 5. Encrypt the data with the keyring and encryption context - final AwsCryptoResult encryptResult = crypto.encrypt(EncryptRequest.builder() - .keyring(keyring) - .encryptionContext(encryptionContext) - .plaintext(EXAMPLE_DATA).build()); - final byte[] ciphertext = encryptResult.getResult(); - - // 6. Decrypt the data - final AwsCryptoResult decryptResult = crypto.decrypt(DecryptRequest.builder() - .keyring(keyring) - .ciphertext(ciphertext).build()); - - // 7. Verify that the encryption context that was used to decrypt the data is the one that you expect. - // This helps to ensure that the ciphertext that you decrypted was the one that you intended. - // - // When verifying, test that your expected encryption context is a subset of the actual encryption context, - // not an exact match. When appropriate, the Encryption SDK adds the signing key to the encryption context. - assert decryptResult.getEncryptionContext().get("ExampleContextKey").equals("ExampleContextValue"); - - // 8. Verify that the decrypted plaintext matches the original plaintext - assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); - } - - /** - * In practice, this key would be saved in a secure location. - * For this demo, we generate a new random key for each operation. - */ - private static SecretKey generateEncryptKey() { - SecureRandom rnd = new SecureRandom(); - byte[] rawKey = new byte[16]; // 128 bits - rnd.nextBytes(rawKey); - return new SecretKeySpec(rawKey, "AES"); - } -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExample.java deleted file mode 100644 index b2cf3010e..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExample.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.AwsCrypto; -import com.amazonaws.encryptionsdk.AwsCryptoResult; -import com.amazonaws.encryptionsdk.DecryptRequest; -import com.amazonaws.encryptionsdk.keyrings.Keyring; -import com.amazonaws.encryptionsdk.keyrings.RawRsaKeyringBuilder.RsaPaddingScheme; -import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; - -import java.security.KeyPair; - -/** - *

- * Decrypts data using the Raw RSA keyring. - */ -public class RawRsaKeyringDecryptExample { - - public static byte[] decrypt(byte[] ciphertext, KeyPair keyPair) { - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a Raw RSA keyring with the private key - final Keyring keyring = StandardKeyrings.rawRsaBuilder() - .keyNamespace("ExampleKeyNamespace") - .keyName("ExampleKeyName") - .paddingScheme(RsaPaddingScheme.OAEP_SHA512_MGF1) - .privateKey(keyPair.getPrivate()).build(); - - // 3. Decrypt the ciphertext with the keyring - final AwsCryptoResult decryptResult = crypto.decrypt(DecryptRequest.builder() - .keyring(keyring) - .ciphertext(ciphertext).build()); - - // 4. Verify that the encryption context that was used to decrypt the data is the one that you expect. - // This helps to ensure that the ciphertext that you decrypted was the one that you intended. - // - // When verifying, test that your expected encryption context is a subset of the actual encryption context, - // not an exact match. When appropriate, the Encryption SDK adds the signing key to the encryption context. - assert decryptResult.getEncryptionContext().get("ExampleContextKey").equals("ExampleContextValue"); - - // 5. Return the decrypted byte array result - return decryptResult.getResult(); - } -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExample.java deleted file mode 100644 index 82a8001f4..000000000 --- a/src/examples/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExample.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.AwsCrypto; -import com.amazonaws.encryptionsdk.AwsCryptoResult; -import com.amazonaws.encryptionsdk.EncryptRequest; -import com.amazonaws.encryptionsdk.keyrings.Keyring; -import com.amazonaws.encryptionsdk.keyrings.RawRsaKeyringBuilder.RsaPaddingScheme; -import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; - -import java.nio.charset.StandardCharsets; -import java.security.PublicKey; -import java.util.Collections; -import java.util.Map; - -/** - * Encrypts data using the Raw RSA keyring. - */ -public class RawRsaKeyringEncryptExample { - - static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); - - public static byte[] encrypt(PublicKey publicKey) { - // 1. Instantiate the SDK - final AwsCrypto crypto = new AwsCrypto(); - - // 2. Instantiate a Raw RSA keyring with the public key - final Keyring keyring = StandardKeyrings.rawRsaBuilder() - .keyNamespace("ExampleKeyNamespace") - .keyName("ExampleKeyName") - .paddingScheme(RsaPaddingScheme.OAEP_SHA512_MGF1) - .publicKey(publicKey).build(); - - // 3. Create an encryption context - // - // Most encrypted data should have an associated encryption context - // to protect integrity. This sample uses placeholder values. - // - // For more information see: - // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management - final Map encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); - - // 4. Encrypt the data with the keyring and encryption context - final AwsCryptoResult encryptResult = crypto.encrypt(EncryptRequest.builder() - .keyring(keyring) - .encryptionContext(encryptionContext) - .plaintext(EXAMPLE_DATA).build()); - - // 5. Return the encrypted byte array result - return encryptResult.getResult(); - } -} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java new file mode 100644 index 000000000..a82f7eea4 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java @@ -0,0 +1,149 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.awskms; + +import com.amazonaws.auth.profile.ProfileCredentialsProvider; +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.AwsKmsClientSupplier; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; +import com.amazonaws.encryptionsdk.kms.StandardAwsKmsClientSuppliers; +import com.amazonaws.services.kms.AWSKMS; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * By default, the KMS keyring uses a client supplier that + * supplies a client with the same configuration for every region. + * If you need different behavior, you can write your own client supplier. + *

+ * One use-case where you might need this is + * if you need different credentials to talk to different AWS regions. + * This might be because you are crossing partitions (ex: "aws" and "aws-cn") + * or if you are working with regions that have separate authentication silos + * like "ap-east-1" and "me-south-1". + *

+ * This example shows how to create a client supplier + * that will supply KMS clients with valid credentials for the target region + * even when working with regions that need different credentials. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For another example of how to use the KMS keyring with a custom client configuration, + * see the {@link CustomKmsClientConfig} example. + *

+ * For examples of how to use the KMS Discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, {@link DiscoveryDecryptInRegionOnly}, + * and {@link DiscoveryDecryptWithPreferredRegions} examples. + */ +public class CustomClientSupplier { + + static class MultiPartitionClientSupplier implements AwsKmsClientSupplier { + + private final AwsKmsClientSupplier chinaSupplier = StandardAwsKmsClientSuppliers.defaultBuilder() + .credentialsProvider(new ProfileCredentialsProvider("china")).build(); + private final AwsKmsClientSupplier middleEastSupplier = StandardAwsKmsClientSuppliers.defaultBuilder() + .credentialsProvider(new ProfileCredentialsProvider("middle-east")).build(); + private final AwsKmsClientSupplier hongKongSupplier = StandardAwsKmsClientSuppliers.defaultBuilder() + .credentialsProvider(new ProfileCredentialsProvider("hong-kong")).build(); + private final AwsKmsClientSupplier defaultSupplier = StandardAwsKmsClientSuppliers.defaultBuilder().build(); + + /** + * Returns a client for the requested region. + * + * @param regionId The AWS region + * @return The AWSKMS client + */ + @Override + public AWSKMS getClient(String regionId) { + if (regionId.startsWith("cn-")) { + return chinaSupplier.getClient(regionId); + } else if (regionId.startsWith("me-")) { + return middleEastSupplier.getClient(regionId); + } else if (regionId.equals("ap-east-1")) { + return hongKongSupplier.getClient(regionId); + } else { + return defaultSupplier.getClient(regionId); + } + } + } + + /** + * Demonstrate an encrypt/decrypt cycle using a KMS keyring with a custom client supplier. + * + * @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 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 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 keyring = StandardKeyrings.awsKmsBuilder() + .generatorKeyId(awsKmsCmk) + .awsKmsClientSupplier(new MultiPartitionClientSupplier()) + .build(); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java new file mode 100644 index 000000000..2ed211b61 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java @@ -0,0 +1,128 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.awskms; + +import com.amazonaws.ClientConfiguration; +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.AwsCryptoResult; +import com.amazonaws.encryptionsdk.DecryptRequest; +import com.amazonaws.encryptionsdk.EncryptRequest; +import com.amazonaws.encryptionsdk.internal.VersionInfo; +import com.amazonaws.encryptionsdk.keyrings.Keyring; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; +import com.amazonaws.encryptionsdk.kms.AwsKmsClientSupplier; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; +import com.amazonaws.encryptionsdk.kms.StandardAwsKmsClientSuppliers; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * By default, the KMS keyring will use the default configurations + * for all KMS clients and will use the default discoverable credentials. + * If you need to change these configurations, + * you can do that using the client supplier. + *

+ * This example shows how to use custom-configured clients with the KMS keyring. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For another example of how to use the KMS keyring with a custom client configuration, + * see the {@link CustomKmsClientConfig} example. + *

+ * For examples of how to use the KMS Discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, {@link DiscoveryDecryptInRegionOnly}, + * and {@link DiscoveryDecryptWithPreferredRegions} examples. + */ +public class CustomKmsClientConfig { + + /** + * Demonstrate an encrypt/decrypt cycle using a KMS keyring with custom KMS client configuration. + * + * @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 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 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"); + + // Prepare your custom configuration values. + // + // Set your custom connection timeout value. + // https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/ClientConfiguration.html + final ClientConfiguration clientConfiguration = new ClientConfiguration() + .withConnectionTimeout(10000) // 10,000 milliseconds + .withUserAgentSuffix(VersionInfo.USER_AGENT); + + // Use your custom configuration values to configure your client supplier. + // For this example we will just use the default credentials provider + // but if you need to, you can set a custom credentials provider as well. + final AwsKmsClientSupplier clientSupplier = StandardAwsKmsClientSuppliers.defaultBuilder() + .clientConfiguration(clientConfiguration) + .build(); + + // Create the keyring that determines how your data keys are protected, + // providing the client supplier that you created. + final Keyring keyring = StandardKeyrings.awsKmsBuilder() + .generatorKeyId(awsKmsCmk) + .awsKmsClientSupplier(clientSupplier) + .build(); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java new file mode 100644 index 000000000..3b9e4b15c --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java @@ -0,0 +1,112 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +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. + *

+ * This example shows how to configure and use a KMS discovery keyring. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For examples of how to use the KMS keyring with custom client configurations, + * see the {@link CustomClientSupplier} + * and {@link CustomKmsClientConfig} examples. + *

+ * 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 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 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 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 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java new file mode 100644 index 000000000..5d40f4d0b --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java @@ -0,0 +1,128 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.awskms; + +import com.amazonaws.arn.Arn; +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 com.amazonaws.encryptionsdk.kms.StandardAwsKmsClientSuppliers; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.singleton; + +/** + * 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. + *

+ * However, sometimes you need to be a *bit* more restrictive than that. + * To address this need, you can use a client supplier to restrict what regions a KMS keyring can talk to. + *

+ * This example shows how to configure and use a KMS regional discovery keyring that is restricted to one region. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For examples of how to use the KMS keyring with custom client configurations, + * see the {@link CustomClientSupplier} + * and {@link CustomKmsClientConfig} examples. + *

+ * For examples of how to use the KMS discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, + * and {@link DiscoveryDecryptWithPreferredRegions} examples. + */ +public class DiscoveryDecryptInRegionOnly { + + /** + * Demonstrate configuring a KMS keyring to only work within a single region. + * + * @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 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 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); + + // Extract the region from the CMK ARN. + final String decryptRegion = Arn.fromString(awsKmsCmk.toString()).getRegion(); + + // Create the KMS discovery keyring that we will use on decrypt. + // + // The client supplier that we specify here will only supply clients for the specified region. + // The keyring only attempts to decrypt data keys if it can get a client for that region, + // so this keyring will now ignore any data keys that were encrypted under a CMK in another region. + final Keyring decryptKeyring = StandardKeyrings.awsKmsDiscoveryBuilder() + .awsKmsClientSupplier(StandardAwsKmsClientSuppliers.allowRegionsBuilder(singleton(decryptRegion)).build()) + .build(); + + // Encrypt your plaintext data. + final AwsCryptoResult 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 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java new file mode 100644 index 000000000..5322af0fa --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java @@ -0,0 +1,144 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +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 com.amazonaws.encryptionsdk.kms.StandardAwsKmsClientSuppliers; +import com.amazonaws.services.kms.AWSKMSClientBuilder; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static java.util.Collections.singleton; + +/** + * 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. + *

+ * However, sometimes you need to be a *bit* more restrictive than that. + * To address this need, you can use a client supplier to restrict what regions a KMS keyring can talk to. + *

+ * A more complex but more common use-case is that you would *prefer* to stay within a region, + * but you would rather make calls to other regions than fail to decrypt the message. + * In this case, you want a keyring that will try to decrypt data keys in this region first, + * then try other regions. + *

+ * This example shows how to configure and use a multi-keyring with the KMS keyring + * to prefer the current AWS region while also failing over to other AWS regions. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For examples of how to use the KMS keyring with custom client configurations, + * see the {@link CustomClientSupplier} + * and {@link CustomKmsClientConfig} examples. + *

+ * For examples of how to use the KMS discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, + * and {@link DiscoveryDecryptInRegionOnly} examples. + */ +public class DiscoveryDecryptWithPreferredRegions { + + /** + * Demonstrate configuring a keyring preferring a particular AWS region and failing over to others. + * + * @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 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 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); + + // To create our decrypt keyring, we need to know our current default AWS region. + final String localRegion = AWSKMSClientBuilder.standard().getRegion(); + + // Now, use that region name to create two KMS discovery keyrings: + // + // One that only works in the local region + final Keyring localRegionDecryptKeyring = StandardKeyrings.awsKmsDiscoveryBuilder() + .awsKmsClientSupplier(StandardAwsKmsClientSuppliers.allowRegionsBuilder(singleton(localRegion)).build()) + .build(); + // and one that will work in any other region but NOT the local region. + final Keyring otherRegionsDecryptKeyring = StandardKeyrings.awsKmsDiscoveryBuilder() + .awsKmsClientSupplier(StandardAwsKmsClientSuppliers.denyRegionsBuilder(singleton(localRegion)).build()) + .build(); + + // Finally, combine those two keyrings into a multi-keyring. + // + // The multi-keyring steps through its member keyrings in the order that you provider them, + // attempting to decrypt every encrypted data key with each keyring before moving on to the next keyring. + // Because of this, otherRegionsDecryptKeyring will not be called + // unless localRegionDecryptKeyring fails to decrypt every encrypted data key. + final Keyring decryptKeyring = StandardKeyrings.multi(localRegionDecryptKeyring, otherRegionsDecryptKeyring); + + // Encrypt your plaintext data. + final AwsCryptoResult 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 multi keyring. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java new file mode 100644 index 000000000..5c47f212c --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java @@ -0,0 +1,132 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +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.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This example shows how to configure and use a KMS keyring with CMKs in multiple regions. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with a single CMK, + * see the {@link SingleCmk} example. + *

+ * For examples of how to use the KMS keyring with custom client configurations, + * see the {@link CustomClientSupplier} + * and {@link CustomKmsClientConfig} examples. + *

+ * For examples of how to use the KMS Discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, + * {@link DiscoveryDecryptInRegionOnly}, + * and {@link DiscoveryDecryptWithPreferredRegions} examples. + */ +public class MultipleRegions { + + /** + * Demonstrate an encrypt/decrypt cycle using a KMS keyring with a single CMK. + * + * @param awsKmsGeneratorCmk The ARN of an AWS KMS CMK that protects data keys + * @param awsKmsAdditionalCmks Additional ARNs of secondary KMS CMKs + * @param sourcePlaintext Plaintext to encrypt + */ + public static void run(final AwsKmsCmkId awsKmsGeneratorCmk, final List awsKmsAdditionalCmks, byte[] sourcePlaintext) { + // Instantiate the 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 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 will encrypt your data keys under all requested CMKs. + final Keyring manyCmksKeyring = StandardKeyrings.awsKmsBuilder() + .generatorKeyId(awsKmsGeneratorCmk) + .keyIds(awsKmsAdditionalCmks) + .build(); + + // Create keyrings that each only use one of the CMKs. + // We will use these later to demonstrate that any of the CMKs can be used to decrypt the message. + // + // We provide these in "keyIds" rather than "generatorKeyId" + // so that these keyrings cannot be used to generate a new data key. + // We will only be using them on decrypt. + final Keyring singleCmkKeyringThatGenerated = StandardKeyrings.awsKmsBuilder() + .keyIds(Collections.singletonList(awsKmsGeneratorCmk)) + .build(); + final Keyring singleCmkKeyringThatEncrypted = StandardKeyrings.awsKmsBuilder() + .keyIds(Collections.singletonList(awsKmsAdditionalCmks.get(0))) + .build(); + + // Encrypt your plaintext data using the keyring that uses all requests CMKs. + final AwsCryptoResult encryptResult = awsEncryptionSdk.encrypt( + EncryptRequest.builder() + .keyring(manyCmksKeyring) + .encryptionContext(encryptionContext) + .plaintext(sourcePlaintext).build()); + final byte[] ciphertext = encryptResult.getResult(); + + // Verify that the header contains the expected number of encrypted data keys (EDKs). + // It should contain one EDK for each CMK. + assert encryptResult.getHeaders().getEncryptedKeyBlobCount() == awsKmsAdditionalCmks.size() + 1; + + // Demonstrate that the ciphertext and plaintext are different + assert !Arrays.equals(ciphertext, sourcePlaintext); + + // Decrypt your encrypted data separately using the single-CMK keyrings. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult decryptResult1 = awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(singleCmkKeyringThatGenerated) + .ciphertext(ciphertext).build()); + final byte[] decrypted1 = decryptResult1.getResult(); + final AwsCryptoResult decryptResult2 = awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(singleCmkKeyringThatEncrypted) + .ciphertext(ciphertext).build()); + final byte[] decrypted2 = decryptResult2.getResult(); + + // Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert Arrays.equals(decrypted1, sourcePlaintext); + assert Arrays.equals(decrypted2, 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(decryptResult1.getEncryptionContext().get(k)); + assert v.equals(decryptResult2.getEncryptionContext().get(k)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java new file mode 100644 index 000000000..4f844db62 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java @@ -0,0 +1,102 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +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; + +/** + * This example shows how to configure and use a KMS keyring with a single KMS CMK. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-kms-keyring + *

+ * For an example of how to use the KMS keyring with CMKs in multiple regions, + * see the {@link MultipleRegions} example. + *

+ * For examples of how to use the KMS keyring with custom client configurations, + * see the {@link CustomClientSupplier} + * and {@link CustomKmsClientConfig} examples. + *

+ * For examples of how to use the KMS Discovery keyring on decrypt, + * see the {@link DiscoveryDecrypt}, + * {@link DiscoveryDecryptInRegionOnly}, + * and {@link DiscoveryDecryptWithPreferredRegions} examples. + */ +public class SingleCmk { + + /** + * Demonstrate an encrypt/decrypt cycle using a KMS keyring with a single CMK. + * + * @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 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 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 keyring = StandardKeyrings.awsKms(awsKmsCmk); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java new file mode 100644 index 000000000..aabbdc439 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java @@ -0,0 +1,157 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.multi; + +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.RawRsaKeyringBuilder.RsaPaddingScheme; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * One use-case that we have seen customers need is + * the ability to enjoy the benefits of AWS KMS during normal operation + * but retain the ability to decrypt encrypted messages without access to AWS KMS. + * This example shows how you can use the multi-keyring to achieve this + * by combining a KMS keyring with a raw RSA keyring. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-multi-keyring + *

+ * For more examples of how to use the KMS keyring, see the keyring/awskms examples. + *

+ * For more examples of how to use the raw RSA keyring, see the keyring/rawrsa examples. + *

+ * In this example we generate a RSA keypair + * but in practice you would want to keep your private key in an HSM + * or other key management system. + *

+ * In this example, we use the one-step encrypt and decrypt APIs. + */ +public class AwsKmsWithEscrow { + + /** + * Demonstrate configuring a keyring to use an AWS KMS CMK and a RSA wrapping key. + * + * @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) throws GeneralSecurityException { + // Instantiate the 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 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 RSA key pair to use with your keyring. + // In practice, you should get this key from a secure key management system such as an HSM. + final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); + kg.initialize(4096); // Escrow keys should be very strong + final KeyPair keyPair = kg.generateKeyPair(); + + // Create the encrypt keyring that only has access to the public key. + final Keyring escrowEncryptKeyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name are defined by you + // and are used by the raw RSA 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-rsa-keyring + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .publicKey(keyPair.getPublic()) + // The padding scheme tells the raw RSA keyring + // how to use your wrapping key to encrypt data keys. + // + // We recommend using OAEP_SHA256_MGF1. + // You should not use PKCS1 unless you require it for backwards compatibility. + .paddingScheme(RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Create the decrypt keyring that has access to the private key. + final Keyring escrowDecryptKeyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name MUST match the encrypt keyring. + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .privateKey(keyPair.getPrivate()) + // The padding scheme MUST match the encrypt keyring. + .paddingScheme(RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Create the KMS keyring that you will use from decryption during normal operations. + final Keyring kmsKeyring = StandardKeyrings.awsKms(awsKmsCmk); + + // Combine the KMS keyring and the escrow encrypt keyring using the multi-keyring. + final Keyring encryptKeyring = StandardKeyrings.multi(kmsKeyring, escrowEncryptKeyring); + + // Encrypt your plaintext data using the multi-keyring. + final AwsCryptoResult encryptResult = awsEncryptionSdk.encrypt( + EncryptRequest.builder() + .keyring(encryptKeyring) + .encryptionContext(encryptionContext) + .plaintext(sourcePlaintext).build()); + final byte[] ciphertext = encryptResult.getResult(); + + // Verify that the header contains the expected number of encrypted data keys (EDKs). + // It should contain one EDK for KMS and one for the escrow key. + assert encryptResult.getHeaders().getEncryptedKeyBlobCount() == 2; + + // Demonstrate that the ciphertext and plaintext are different. + assert !Arrays.equals(ciphertext, sourcePlaintext); + + // Decrypt your encrypted data separately using the KMS keyring and the escrow decrypt keyring. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult decryptedKmsResult = awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(kmsKeyring) + .ciphertext(ciphertext).build()); + final byte[] decryptedKms = decryptedKmsResult.getResult(); + final AwsCryptoResult decryptedEscrowResult = awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(escrowDecryptKeyring) + .ciphertext(ciphertext).build()); + final byte[] decryptedEscrow = decryptedKmsResult.getResult(); + + // Demonstrate that the decrypted plaintext is identical to the original plaintext. + assert Arrays.equals(decryptedKms, sourcePlaintext); + assert Arrays.equals(decryptedEscrow, 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(decryptedKmsResult.getEncryptionContext().get(k)); + assert v.equals(decryptedEscrowResult.getEncryptionContext().get(k)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java new file mode 100644 index 000000000..3c555ff7d --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java @@ -0,0 +1,111 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +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. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring + *

+ * 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 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 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[16]; // 128 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 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java new file mode 100644 index 000000000..e006a0150 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java @@ -0,0 +1,152 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.rawrsa; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.AwsCryptoResult; +import com.amazonaws.encryptionsdk.DecryptRequest; +import com.amazonaws.encryptionsdk.EncryptRequest; +import com.amazonaws.encryptionsdk.exception.AwsCryptoException; +import com.amazonaws.encryptionsdk.keyrings.Keyring; +import com.amazonaws.encryptionsdk.keyrings.RawRsaKeyringBuilder; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * One of the benefits of asymmetric encryption + * is that you can encrypt with just the public key. + * This means that you give someone the ability to encrypt + * without giving them the ability to decrypt. + *

+ * The raw RSA keyring supports encrypt-only operations + * when it only has access to a public key. + *

+ * This example shows how to construct and use the raw RSA keyring + * to encrypt with only the public key and decrypt with the private key. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring + *

+ * In this example, we use the one-step encrypt and decrypt APIs. + */ +public class PublicPrivateKeySeparate { + + /** + * Demonstrate an encrypt/decrypt cycle using separate public and private raw RSA keyrings. + * + * @param sourcePlaintext Plaintext to encrypt + */ + public static void run(final byte[] sourcePlaintext) throws GeneralSecurityException { + // Instantiate the 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 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 RSA key pair to use with your keyring. + // In practice, you should get this key from a secure key management system such as an HSM. + final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); + kg.initialize(4096); // Escrow keys should be very strong + final KeyPair keyPair = kg.generateKeyPair(); + + // Create the keyring that determines how your data keys are protected. + // + // Create the encrypt keyring that only has access to the public key. + final Keyring publicKeyKeyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name are defined by you + // and are used by the raw RSA 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-rsa-keyring + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .publicKey(keyPair.getPublic()) + // The padding scheme tells the raw RSA keyring + // how to use your wrapping key to encrypt data keys. + // + // We recommend using OAEP_SHA256_MGF1. + // You should not use PKCS1 unless you require it for backwards compatibility. + .paddingScheme(RawRsaKeyringBuilder.RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Create the decrypt keyring that has access to the private key. + final Keyring privateKeyKeyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name MUST match the encrypt keyring. + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .privateKey(keyPair.getPrivate()) + // The padding scheme MUST match the encrypt keyring. + .paddingScheme(RawRsaKeyringBuilder.RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Encrypt your plaintext data using the encrypt keyring. + final AwsCryptoResult encryptResult = awsEncryptionSdk.encrypt( + EncryptRequest.builder() + .keyring(publicKeyKeyring) + .encryptionContext(encryptionContext) + .plaintext(sourcePlaintext).build()); + final byte[] ciphertext = encryptResult.getResult(); + + // Demonstrate that the ciphertext and plaintext are different + assert !Arrays.equals(ciphertext, sourcePlaintext); + + // Try to decrypt your encrypted data using the *encrypt* keyring. + // This demonstrates that you cannot decrypt using the public key. + try { + awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(publicKeyKeyring) + .ciphertext(ciphertext) + .build()); + assert false; + } catch (AwsCryptoException ex) { + // The public key cannot decrypt. + // Reaching this point means everything is working as expected. + } + + // Decrypt your encrypted data using the decrypt keyring. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( + DecryptRequest.builder() + .keyring(privateKeyKeyring) + .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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java new file mode 100644 index 000000000..4a06c4ac1 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java @@ -0,0 +1,117 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.keyring.rawrsa; + +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.RawRsaKeyringBuilder; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; + +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * This examples shows how to configure and use a raw RSA keyring using a pre-loaded RSA key pair. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring + *

+ * In this example, we use the one-step encrypt and decrypt APIs. + */ +public class RawRsa { + + /** + * Demonstrate an encrypt/decrypt cycle using a raw RSA keyring. + * + * @param sourcePlaintext Plaintext to encrypt + */ + public static void run(final byte[] sourcePlaintext) throws GeneralSecurityException { + // Instantiate the 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 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 RSA key pair to use with your keyring. + // In practice, you should get this key from a secure key management system such as an HSM. + final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); + kg.initialize(4096); // Escrow keys should be very strong + final KeyPair keyPair = kg.generateKeyPair(); + + // Create the keyring that determines how your data keys are protected. + final Keyring keyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name are defined by you + // and are used by the raw RSA 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-rsa-keyring + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .privateKey(keyPair.getPrivate()) + .publicKey(keyPair.getPublic()) + // The padding scheme tells the raw RSA keyring + // how to use your wrapping key to encrypt data keys. + // + // We recommend using OAEP_SHA256_MGF1. + // You should not use PKCS1 unless you require it for backwards compatibility. + .paddingScheme(RawRsaKeyringBuilder.RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java new file mode 100644 index 000000000..8bce47e66 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java @@ -0,0 +1,91 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.legacy; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.CryptoResult; +import com.amazonaws.encryptionsdk.kms.KmsMasterKey; +import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; + +/** + *

+ * Encrypts and then decrypts data using an AWS KMS customer master key. + * NOTE: Master key providers are deprecated and replaced by keyrings. + * We keep these older examples as reference material, + * but we recommend that you use the new examples in examples/keyring + * The new examples reflect our current guidance for using the library. + *

+ * Arguments: + *

    + *
  1. Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master + * key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html + *
+ */ +public class BasicEncryptionExample { + + private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8); + + public static void main(final String[] args) { + final String keyArn = args[0]; + + encryptAndDecrypt(keyArn); + } + + static void encryptAndDecrypt(final String keyArn) { + // 1. Instantiate the SDK + final AwsCrypto crypto = new AwsCrypto(); + + // 2. Instantiate a KMS master key provider + final KmsMasterKeyProvider masterKeyProvider = KmsMasterKeyProvider.builder().withKeysForEncryption(keyArn).build(); + + // 3. Create an encryption context + // + // Most encrypted data should have an associated encryption context + // to protect integrity. This sample uses placeholder values. + // + // For more information see: + // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management + final Map encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); + + // 4. Encrypt the data + final CryptoResult encryptResult = crypto.encryptData(masterKeyProvider, EXAMPLE_DATA, encryptionContext); + final byte[] ciphertext = encryptResult.getResult(); + + // 5. Decrypt the data + final CryptoResult decryptResult = crypto.decryptData(masterKeyProvider, ciphertext); + + // 6. Before verifying the plaintext, verify that the customer master key that + // was used in the encryption operation was the one supplied to the master key provider. + if (!decryptResult.getMasterKeyIds().get(0).equals(keyArn)) { + throw new IllegalStateException("Wrong key ID!"); + } + + // 7. Also, verify that the encryption context in the result contains the + // encryption context supplied to the encryptData method. Because the + // SDK can add values to the encryption context, don't require that + // the entire context matches. + if (!encryptionContext.entrySet().stream() + .allMatch(e -> e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey())))) { + throw new IllegalStateException("Wrong Encryption Context!"); + } + + // 8. Verify that the decrypted plaintext matches the original plaintext + assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java new file mode 100644 index 000000000..1405377f8 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java @@ -0,0 +1,172 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples.legacy; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.CryptoOutputStream; +import com.amazonaws.encryptionsdk.MasterKeyProvider; +import com.amazonaws.encryptionsdk.jce.JceMasterKey; +import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; +import com.amazonaws.encryptionsdk.multi.MultipleProviderFactory; +import com.amazonaws.util.IOUtils; + +/** + *

+ * Encrypts a file using both KMS and an asymmetric key pair. + * NOTE: Master key providers are deprecated and replaced by keyrings. + * We keep these older examples as reference material, + * but we recommend that you use the new examples in examples/keyring + * The new examples reflect our current guidance for using the library. + * + *

+ * Arguments: + *

    + *
  1. Key ARN: For help finding the Amazon Resource Name (ARN) of your KMS customer master + * key (CMK), see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html + * + *
  2. Name of file containing plaintext data to encrypt + *
+ * + * You might use AWS Key Management Service (KMS) for most encryption and decryption operations, but + * still want the option of decrypting your data offline independently of KMS. This sample + * demonstrates one way to do this. + * + * The sample encrypts data under both a KMS customer master key (CMK) and an "escrowed" RSA key pair + * so that either key alone can decrypt it. You might commonly use the KMS CMK for decryption. However, + * at any time, you can use the private RSA key to decrypt the ciphertext independent of KMS. + * + * This sample uses the JCEMasterKey class to generate a RSA public-private key pair + * and saves the key pair in memory. In practice, you would store the private key in a secure offline + * location, such as an offline HSM, and distribute the public key to your development team. + * + */ +public class EscrowedEncryptExample { + private static PublicKey publicEscrowKey; + private static PrivateKey privateEscrowKey; + + public static void main(final String[] args) throws Exception { + // This sample generates a new random key for each operation. + // In practice, you would distribute the public key and save the private key in secure + // storage. + generateEscrowKeyPair(); + + final String kmsArn = args[0]; + final String fileName = args[1]; + + standardEncrypt(kmsArn, fileName); + standardDecrypt(kmsArn, fileName); + + escrowDecrypt(fileName); + } + + private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception { + // Encrypt with the KMS CMK and the escrowed public key + // 1. Instantiate the SDK + final AwsCrypto crypto = new AwsCrypto(); + + // 2. Instantiate a KMS master key provider + final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn); + + // 3. Instantiate a JCE master key provider + // Because the user does not have access to the private escrow key, + // they pass in "null" for the private key parameter. + final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow", + "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); + + // 4. Combine the providers into a single master key provider + final MasterKeyProvider provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub); + + // 5. Encrypt the file + // To simplify the code, we omit the encryption context. Production code should always + // use an encryption context. For an example, see the other SDK samples. + final FileInputStream in = new FileInputStream(fileName); + final FileOutputStream out = new FileOutputStream(fileName + ".encrypted"); + final CryptoOutputStream encryptingStream = crypto.createEncryptingStream(provider, out); + + IOUtils.copy(in, encryptingStream); + in.close(); + encryptingStream.close(); + } + + private static void standardDecrypt(final String kmsArn, final String fileName) throws Exception { + // Decrypt with the KMS CMK and the escrow public key. You can use a combined provider, + // as shown here, or just the KMS master key provider. + + // 1. Instantiate the SDK + final AwsCrypto crypto = new AwsCrypto(); + + // 2. Instantiate a KMS master key provider + final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn); + + // 3. Instantiate a JCE master key provider + // Because the user does not have access to the private + // escrow key, they pass in "null" for the private key parameter. + final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow", + "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); + + // 4. Combine the providers into a single master key provider + final MasterKeyProvider provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub); + + // 5. Decrypt the file + // To simplify the code, we omit the encryption context. Production code should always + // use an encryption context. For an example, see the other SDK samples. + final FileInputStream in = new FileInputStream(fileName + ".encrypted"); + final FileOutputStream out = new FileOutputStream(fileName + ".decrypted"); + final CryptoOutputStream decryptingStream = crypto.createDecryptingStream(provider, out); + IOUtils.copy(in, decryptingStream); + in.close(); + decryptingStream.close(); + } + + private static void escrowDecrypt(final String fileName) throws Exception { + // You can decrypt the stream using only the private key. + // This method does not call KMS. + + // 1. Instantiate the SDK + final AwsCrypto crypto = new AwsCrypto(); + + // 2. Instantiate a JCE master key provider + // This method call uses the escrowed private key, not null + final JceMasterKey escrowPriv = JceMasterKey.getInstance(publicEscrowKey, privateEscrowKey, "Escrow", "Escrow", + "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); + + // 3. Decrypt the file + // To simplify the code, we omit the encryption context. Production code should always + // use an encryption context. For an example, see the other SDK samples. + final FileInputStream in = new FileInputStream(fileName + ".encrypted"); + final FileOutputStream out = new FileOutputStream(fileName + ".deescrowed"); + final CryptoOutputStream decryptingStream = crypto.createDecryptingStream(escrowPriv, out); + IOUtils.copy(in, decryptingStream); + in.close(); + decryptingStream.close(); + + } + + private static void generateEscrowKeyPair() throws GeneralSecurityException { + final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); + kg.initialize(4096); // Escrow keys should be very strong + final KeyPair keyPair = kg.generateKeyPair(); + publicEscrowKey = keyPair.getPublic(); + privateEscrowKey = keyPair.getPrivate(); + + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java new file mode 100644 index 000000000..1b022bc5f --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java @@ -0,0 +1,103 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.amazonaws.crypto.examples.legacy; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.security.SecureRandom; +import java.util.Collections; +import java.util.Map; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import com.amazonaws.encryptionsdk.AwsCrypto; +import com.amazonaws.encryptionsdk.CryptoInputStream; +import com.amazonaws.encryptionsdk.MasterKey; +import com.amazonaws.encryptionsdk.jce.JceMasterKey; +import com.amazonaws.util.IOUtils; + +/** + *

+ * Encrypts and then decrypts a file under a random key. + * NOTE: Master key providers are deprecated and replaced by keyrings. + * We keep these older examples as reference material, + * but we recommend that you use the new examples in examples/keyring + * The new examples reflect our current guidance for using the library. + * + *

+ * Arguments: + *

    + *
  1. Name of file containing plaintext data to encrypt + *
+ * + *

+ * This program demonstrates using a standard Java {@link SecretKey} object as a {@link MasterKey} to + * encrypt and decrypt streaming data. + */ +public class FileStreamingExample { + private static String srcFile; + + public static void main(String[] args) throws IOException { + srcFile = args[0]; + + // In this example, we generate a random key. In practice, + // you would get a key from an existing store + SecretKey cryptoKey = retrieveEncryptionKey(); + + // Create a JCE master key provider using the random key and an AES-GCM encryption algorithm + JceMasterKey masterKey = JceMasterKey.getInstance(cryptoKey, "Example", "RandomKey", "AES/GCM/NoPadding"); + + // Instantiate the SDK + AwsCrypto crypto = new AwsCrypto(); + + // Create an encryption context to identify this ciphertext + Map context = Collections.singletonMap("Example", "FileStreaming"); + + // Because the file might be to large to load into memory, we stream the data, instead of + //loading it all at once. + FileInputStream in = new FileInputStream(srcFile); + CryptoInputStream encryptingStream = crypto.createEncryptingStream(masterKey, in, context); + + FileOutputStream out = new FileOutputStream(srcFile + ".encrypted"); + IOUtils.copy(encryptingStream, out); + encryptingStream.close(); + out.close(); + + // Decrypt the file. Verify the encryption context before returning the plaintext. + in = new FileInputStream(srcFile + ".encrypted"); + CryptoInputStream decryptingStream = crypto.createDecryptingStream(masterKey, in); + // Does it contain the expected encryption context? + if (!"FileStreaming".equals(decryptingStream.getCryptoResult().getEncryptionContext().get("Example"))) { + throw new IllegalStateException("Bad encryption context"); + } + + // Return the plaintext data + out = new FileOutputStream(srcFile + ".decrypted"); + IOUtils.copy(decryptingStream, out); + decryptingStream.close(); + out.close(); + } + + /** + * In practice, this key would be saved in a secure location. + * For this demo, we generate a new random key for each operation. + */ + private static SecretKey retrieveEncryptionKey() { + SecureRandom rnd = new SecureRandom(); + byte[] rawKey = new byte[16]; // 128 bits + rnd.nextBytes(rawKey); + return new SecretKeySpec(rawKey, "AES"); + } +} diff --git a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/LambdaDecryptAndWriteExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java similarity index 97% rename from src/examples/java/com/amazonaws/crypto/examples/datakeycaching/LambdaDecryptAndWriteExample.java rename to src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java index 2419ebb51..c1c662cb9 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/LambdaDecryptAndWriteExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except * in compliance with the License. A copy of the License is located at @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package com.amazonaws.crypto.examples.datakeycaching; +package com.amazonaws.crypto.examples.legacy; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; diff --git a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/MultiRegionRecordPusherExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java similarity index 97% rename from src/examples/java/com/amazonaws/crypto/examples/datakeycaching/MultiRegionRecordPusherExample.java rename to src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java index 62ff53d45..16817bfea 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/MultiRegionRecordPusherExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except * in compliance with the License. A copy of the License is located at @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package com.amazonaws.crypto.examples.datakeycaching; +package com.amazonaws.crypto.examples.legacy; import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.encryptionsdk.AwsCrypto; diff --git a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java similarity index 98% rename from src/examples/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExample.java rename to src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java index fa14d7702..4babf5c32 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java @@ -11,7 +11,7 @@ * specific language governing permissions and limitations under the License. */ -package com.amazonaws.crypto.examples.datakeycaching; +package com.amazonaws.crypto.examples.legacy; import com.amazonaws.encryptionsdk.AwsCrypto; import com.amazonaws.encryptionsdk.CryptoMaterialsManager; diff --git a/src/test/java/com/amazonaws/crypto/examples/BasicEncryptionExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/BasicEncryptionExampleTest.java deleted file mode 100644 index 95405fa2b..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/BasicEncryptionExampleTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.TestUtils; -import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; -import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag(TestUtils.TAG_INTEGRATION) -class BasicEncryptionExampleTest { - - @Test - void testEncryptAndDecrypt() { - BasicEncryptionExample.encryptAndDecrypt(AwsKmsCmkId.fromString(KMSTestFixtures.TEST_KEY_IDS[0])); - } -} diff --git a/src/test/java/com/amazonaws/crypto/examples/EscrowedEncryptExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/EscrowedEncryptExampleTest.java deleted file mode 100644 index 6e3cf5137..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/EscrowedEncryptExampleTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.TestUtils; -import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; -import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import java.security.GeneralSecurityException; - -@Tag(TestUtils.TAG_INTEGRATION) -class EscrowedEncryptExampleTest { - - @Test - void testEncryptAndDecrypt() throws GeneralSecurityException { - EscrowedEncryptExample.escrowEncryptAndDecrypt(AwsKmsCmkId.fromString(KMSTestFixtures.TEST_KEY_IDS[0])); - } -} diff --git a/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java b/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java new file mode 100644 index 000000000..abbc7b4b1 --- /dev/null +++ b/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java @@ -0,0 +1,129 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except + * in compliance with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package com.amazonaws.crypto.examples; + +import com.amazonaws.encryptionsdk.TestUtils; +import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; +import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.TestFactory; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.fail; + +@Tag(TestUtils.TAG_INTEGRATION) +class ExamplesTest { + + private static final Logger LOGGER = Logger.getLogger(ExamplesTest.class.getName()); + private static final String RUN_METHOD_NAME = "run"; + private static final String TEST_CLASS_SUFFIX = "Test"; + private static final byte[] STATIC_PLAINTEXT = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " + + "Praesent non feugiat leo. Aenean iaculis tellus ut velit consectetur, " + + "quis convallis orci eleifend. Sed eu dictum sapien. Nulla facilisi. Suspendisse potenti. " + + "Proin vehicula vehicula maximus. Donec varius et elit vel rutrum. Nulla lacinia neque turpis," + + " quis consequat orci pharetra et. Etiam consequat ullamcorper mauris. Vivamus molestie mollis " + + "mauris a gravida. Curabitur sed bibendum nisl. Cras varius tortor non erat sodales, quis congue" + + " tellus laoreet. Etiam fermentum purus eu diam sagittis, vitae commodo est vehicula. " + + "Nulla feugiat viverra orci vel interdum. Quisque pulvinar elit eget nulla facilisis varius. " + + "Mauris at suscipit sem. Aliquam in purus ut velit fringilla volutpat id non mi. " + + "Curabitur quis nunc eleifend, ornare lectus non, fringilla quam. Nam maximus volutpat placerat. " + + "Nulla ullamcorper lorem velit, nec sagittis ex tristique posuere. Aliquam fringilla magna commodo" + + " libero faucibus tempor. Vestibulum non ligula tincidunt, finibus sapien in, sollicitudin " + + "ex. Pellentesque congue laoreet mi in condimentum. Cras convallis nisi ac nunc tincidunt " + + "venenatis. Suspendisse urna elit, cursus eu lacus a, aliquet porttitor mi. " + + "Nulla vel congue nibh, sed condimentum dui. Ut ante ligula, blandit eu finibus nec, " + + "scelerisque quis eros. Maecenas gravida odio eget nibh dictum, dictum varius lacus interdum. " + + "Integer quis nulla vulputate, rhoncus diam vitae, mollis mauris. Sed ut porttitor dolor. " + + "Fusce ut justo a ex bibendum imperdiet nec sit amet magna. Sed ullamcorper luctus augue, " + + "tempor viverra elit interdum sed. Cras sit amet arcu eu turpis molestie sollicitudin. " + + "Curabitur fermentum varius nibh, ut aliquet nisi. Aliquam id tempus tellus. " + + "Nulla porttitor nulla at nibh interdum, quis sollicitudin erat egestas. " + + "Ut blandit mauris quis efficitur efficitur. Morbi neque sapien, posuere ut aliquam eget, " + + "aliquam at velit. Morbi sit amet rhoncus felis, et hendrerit sem. Nulla porta dictum ligula " + + "eget iaculis. Cras lacinia ligula quis risus ultrices, sed consectetur metus imperdiet. " + + "Nullam id enim vestibulum nibh ultricies auctor. Morbi neque lacus, faucibus vitae commodo quis, " + + "malesuada sed velit.").getBytes(StandardCharsets.UTF_8); + + @TestFactory + Stream testExamples() { + final List> exampleClasses = ReflectionSupport.findAllClassesInPackage(getClass().getPackage().getName(), + c -> Arrays.stream(c.getDeclaredMethods()).anyMatch(m -> m.getName().equals(RUN_METHOD_NAME)), + c -> !c.endsWith(TEST_CLASS_SUFFIX)); + + return exampleClasses.stream() + .map(c -> ReflectionSupport.findMethods(c, m -> m.getName().equals(RUN_METHOD_NAME), HierarchyTraversalMode.TOP_DOWN).get(0)) + .map(ExamplesTest::createTest); + } + + /** + * Creates a DynamicTest for the given method, matching each parameter type + * to the 4 parameter types that we have predefined values for. + */ + private static DynamicTest createTest(Method method) { + final Class[] parameterTypes = method.getParameterTypes(); + final Object[] parameterValues = new Object[parameterTypes.length]; + + for (int i = 0; i < parameterTypes.length; i++) { + if (parameterTypes[i].isAssignableFrom(AwsKmsCmkId.class)) { + parameterValues[i] = AwsKmsCmkId.fromString(KMSTestFixtures.TEST_KEY_IDS[0]); + } else if (parameterTypes[i].isAssignableFrom(List.class)) { + parameterValues[i] = Collections.singletonList(AwsKmsCmkId.fromString(KMSTestFixtures.TEST_KEY_IDS[1])); + } else if (parameterTypes[i].isAssignableFrom(byte[].class)) { + parameterValues[i] = STATIC_PLAINTEXT; + } else if (parameterTypes[i].isAssignableFrom(File.class)) { + try { + final File tempFile = File.createTempFile(method.getDeclaringClass().getSimpleName(), ".tmp"); + tempFile.deleteOnExit(); + + try (OutputStream os = Files.newOutputStream(tempFile.toPath())) { + os.write(STATIC_PLAINTEXT); + } + + parameterValues[i] = tempFile; + } catch (IOException e) { + fail("Failed to create temp file", e); + } + } else { + LOGGER.info(String.format("Setting unsupported parameter type[%s] to null", parameterTypes[i])); + parameterValues[i] = null; + } + } + + return DynamicTest.dynamicTest(method.getDeclaringClass().getName(), () -> { + try { + method.invoke(null, parameterValues); + } catch (IllegalAccessException e) { + fail(method.getDeclaringClass().getName() + " failed", e); + } catch (InvocationTargetException e) { + fail(method.getDeclaringClass().getName() + " failed", e.getCause()); + } + }); + } + +} diff --git a/src/test/java/com/amazonaws/crypto/examples/FileStreamingExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/FileStreamingExampleTest.java deleted file mode 100644 index 28b3f8f66..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/FileStreamingExampleTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.jupiter.api.Test; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; - -class FileStreamingExampleTest { - - @Test - void testEncryptAndDecrypt() throws IOException { - final File tempFile = File.createTempFile("FileStreamingExampleTest-TempTestData", ".tmp"); - final File encryptedFile = new File(tempFile.getPath() + ".encrypted"); - final File decryptedFile = new File(tempFile.getPath() + ".decrypted"); - tempFile.deleteOnExit(); - encryptedFile.deleteOnExit(); - decryptedFile.deleteOnExit(); - - try (BufferedWriter writer = Files.newBufferedWriter(tempFile.toPath())) { - for (int i = 0; i < 1000 ; i++) { - writer.write(RandomStringUtils.randomAlphanumeric(100)); - writer.newLine(); - } - } - - FileStreamingExample.encryptAndDecrypt(tempFile, encryptedFile, decryptedFile); - } -} diff --git a/src/test/java/com/amazonaws/crypto/examples/RawAesKeyringExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/RawAesKeyringExampleTest.java deleted file mode 100644 index fa4d2906b..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/RawAesKeyringExampleTest.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import org.junit.jupiter.api.Test; - -class RawAesKeyringExampleTest { - - @Test - void testEncryptAndDecrypt() { - RawAesKeyringExample.encryptAndDecrypt(); - } -} diff --git a/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExampleTest.java deleted file mode 100644 index ca4c165f1..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringDecryptExampleTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import org.junit.jupiter.api.Test; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -class RawRsaKeyringDecryptExampleTest { - - @Test - void testDecrypt() throws Exception { - final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); - final KeyPair keyPair = kg.generateKeyPair(); - - byte[] ciphertext = RawRsaKeyringEncryptExample.encrypt(keyPair.getPublic()); - byte[] decryptedResult = RawRsaKeyringDecryptExample.decrypt(ciphertext, keyPair); - - assertArrayEquals(RawRsaKeyringEncryptExample.EXAMPLE_DATA, decryptedResult); - } - -} diff --git a/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExampleTest.java deleted file mode 100644 index 0329b4e48..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/RawRsaKeyringEncryptExampleTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples; - -import com.amazonaws.encryptionsdk.AwsCrypto; -import com.amazonaws.encryptionsdk.DecryptRequest; -import com.amazonaws.encryptionsdk.keyrings.Keyring; -import com.amazonaws.encryptionsdk.keyrings.RawRsaKeyringBuilder.RsaPaddingScheme; -import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; -import org.junit.jupiter.api.Test; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; - -class RawRsaKeyringEncryptExampleTest { - - @Test - void testEncrypt() throws Exception { - final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); - final KeyPair keyPair = kg.generateKeyPair(); - - byte[] ciphertext = RawRsaKeyringEncryptExample.encrypt(keyPair.getPublic()); - - final Keyring keyring = StandardKeyrings.rawRsaBuilder() - .keyNamespace("ExampleKeyNamespace") - .keyName("ExampleKeyName") - .privateKey(keyPair.getPrivate()) - .paddingScheme(RsaPaddingScheme.OAEP_SHA512_MGF1) - .build(); - - - final AwsCrypto awsCrypto = new AwsCrypto(); - byte[] decryptedResult = awsCrypto.decrypt(DecryptRequest.builder() - .keyring(keyring) - .ciphertext(ciphertext) - .build()).getResult(); - - assertArrayEquals(RawRsaKeyringEncryptExample.EXAMPLE_DATA, decryptedResult); - } - -} diff --git a/src/test/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExampleTest.java b/src/test/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExampleTest.java deleted file mode 100644 index e1ebb3be9..000000000 --- a/src/test/java/com/amazonaws/crypto/examples/datakeycaching/SimpleDataKeyCachingExampleTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package com.amazonaws.crypto.examples.datakeycaching; - -import com.amazonaws.encryptionsdk.TestUtils; -import com.amazonaws.encryptionsdk.kms.AwsKmsCmkId; -import com.amazonaws.encryptionsdk.kms.KMSTestFixtures; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag(TestUtils.TAG_INTEGRATION) -class SimpleDataKeyCachingExampleTest { - - @Test - void testEncryptWithCaching() { - SimpleDataKeyCachingExample.encryptWithCaching(AwsKmsCmkId.fromString(KMSTestFixtures.TEST_KEY_IDS[0])); - } -} From 2ad02ff6a2750446a740973526e5f1413816c7d7 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Mon, 23 Mar 2020 14:00:26 -0700 Subject: [PATCH 2/6] Updated wording and copyright notice --- src/examples/README.md | 26 ++++++++++++++++++- .../examples/FileStreamingDefaults.java | 23 +++++----------- .../examples/InMemoryStreamingDefaults.java | 18 +++---------- .../crypto/examples/OneStepDefaults.java | 18 +++---------- .../crypto/examples/OneStepUnsigned.java | 18 +++---------- .../keyring/awskms/CustomClientSupplier.java | 18 +++---------- .../keyring/awskms/CustomKmsClientConfig.java | 18 +++---------- .../keyring/awskms/DiscoveryDecrypt.java | 18 +++---------- .../awskms/DiscoveryDecryptInRegionOnly.java | 18 +++---------- .../DiscoveryDecryptWithPreferredRegions.java | 18 +++---------- .../keyring/awskms/MultipleRegions.java | 18 +++---------- .../examples/keyring/awskms/SingleCmk.java | 18 +++---------- .../keyring/multi/AwsKmsWithEscrow.java | 18 +++---------- .../examples/keyring/rawaes/RawAes.java | 18 +++---------- .../rawrsa/PublicPrivateKeySeparate.java | 18 +++---------- .../examples/keyring/rawrsa/RawRsa.java | 18 +++---------- .../legacy/BasicEncryptionExample.java | 16 +++--------- .../legacy/EscrowedEncryptExample.java | 20 ++++---------- .../examples/legacy/FileStreamingExample.java | 16 +++--------- .../legacy/LambdaDecryptAndWriteExample.java | 14 ++-------- .../MultiRegionRecordPusherExample.java | 14 ++-------- .../legacy/SimpleDataKeyCachingExample.java | 16 +++--------- .../crypto/examples/ExamplesTest.java | 14 ++-------- 23 files changed, 108 insertions(+), 303 deletions(-) diff --git a/src/examples/README.md b/src/examples/README.md index ed94c6761..afe262e49 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -21,7 +21,31 @@ you need to describe how you want the library to protect your data keys. You can do this using [keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers), or using [master key providers](#master-key-providers). -These examples will show you how. +These examples will show you how yo use the configuration tools that we include for you +as well as how to create some of your own. We start with AWS KMS examples, then show +how to use other wrapping keys. + +* Using AWS Key Management Service (AWS KMS) + * How to use a single AWS KMS CMK + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java) + * How to use multiple AWS KMS CMKs in different regions + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java) + * How to decrypt when you don't know the CMK + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java) + * How to decrypt within a region + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java) + * How to decrypt with a preferred region but failover to others + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java) +* Using raw wrapping keys + * How to use a raw AES wrapping key + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java) + * How to use a raw RSA wrapping key + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java) + * How to encrypt with a raw RSA public key wrapping key without access to the private key + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java) +* Combining wrapping keys + * How to combine AWS KMS with an offline escrow key + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java) ### Keyrings diff --git a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java index 917fe7636..10d9465d7 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; @@ -53,7 +43,7 @@ public class FileStreamingDefaults { * @param sourcePlaintextFile Plaintext file to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFile) throws IOException { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // We assume that you can also write to the directory containing the plaintext file, @@ -63,7 +53,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFi encryptedFile.deleteOnExit(); decryptedFile.deleteOnExit(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); @@ -84,7 +74,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFi .encryptionContext(encryptionContext) .inputStream(new FileInputStream(sourcePlaintextFile)).build())) { - // Copy the encrypted data into the encrypted file. + // Encrypt the data and write the ciphertext to the encrypted file. try (FileOutputStream out = new FileOutputStream(encryptedFile)) { IOUtils.copy(encryptingStream, out); } @@ -111,7 +101,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFi assert v.equals(decryptResult.getEncryptionContext().get(k)); }); - // Copy the plaintext data to a file + // Now that we are more confident that we will decrypt the right message, + // we can start decrypting. try (FileOutputStream out = new FileOutputStream(decryptedFile)) { IOUtils.copy(decryptingStream, out); } diff --git a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java index 97dcf91b0..333dcc0e8 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; @@ -50,10 +40,10 @@ public class InMemoryStreamingDefaults { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) throws IOException { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java index cd3b5b5c1..c39afc022 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; @@ -42,10 +32,10 @@ public class OneStepDefaults { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java index 86f921c0b..73def3d22 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; @@ -55,11 +45,11 @@ public class OneStepUnsigned { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK and specify the algorithm suite that we want to use. + // Instantiate the AWS Encryption SDK and specify the algorithm suite that we want to use. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); awsEncryptionSdk.setEncryptionAlgorithm(CryptoAlgorithm.ALG_AES_256_GCM_IV12_TAG16_HKDF_SHA256); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java index a82f7eea4..8825fbf85 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -95,10 +85,10 @@ public AWSKMS getClient(String regionId) { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java index 2ed211b61..7acfcac54 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -58,10 +48,10 @@ public class CustomKmsClientConfig { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java index 3b9e4b15c..2393bd5f9 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -58,10 +48,10 @@ public class DiscoveryDecrypt { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java index 5d40f4d0b..808ddf607 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -65,10 +55,10 @@ public class DiscoveryDecryptInRegionOnly { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java index 5322af0fa..2e0765f36 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -71,10 +61,10 @@ public class DiscoveryDecryptWithPreferredRegions { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java index 5c47f212c..3eda20746 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -54,10 +44,10 @@ public class MultipleRegions { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsGeneratorCmk, final List awsKmsAdditionalCmks, byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java index 4f844db62..be6fbe881 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.awskms; @@ -51,10 +41,10 @@ public class SingleCmk { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java index aabbdc439..88e9dd59a 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.multi; @@ -57,10 +47,10 @@ public class AwsKmsWithEscrow { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) throws GeneralSecurityException { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java index 3c555ff7d..f8388d1b3 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.rawaes; @@ -42,10 +32,10 @@ public class RawAes { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final byte[] sourcePlaintext) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java index e006a0150..6e371d163 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.rawrsa; @@ -53,10 +43,10 @@ public class PublicPrivateKeySeparate { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityException { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java index 4a06c4ac1..719df4cc9 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.keyring.rawrsa; @@ -43,10 +33,10 @@ public class RawRsa { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityException { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto awsEncryptionSdk = new AwsCrypto(); - // Prepare your encryption context + // Prepare your encryption context. // https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context final Map encryptionContext = new HashMap<>(); encryptionContext.put("encryption", "context"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java index 8bce47e66..b38524836 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/BasicEncryptionExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; @@ -48,7 +38,7 @@ public static void main(final String[] args) { } static void encryptAndDecrypt(final String keyArn) { - // 1. Instantiate the SDK + // 1. Instantiate the AWS Encryption SDK final AwsCrypto crypto = new AwsCrypto(); // 2. Instantiate a KMS master key provider diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java index 1405377f8..e463704c9 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; @@ -80,7 +70,7 @@ public static void main(final String[] args) throws Exception { private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception { // Encrypt with the KMS CMK and the escrowed public key - // 1. Instantiate the SDK + // 1. Instantiate the AWS Encryption SDK final AwsCrypto crypto = new AwsCrypto(); // 2. Instantiate a KMS master key provider @@ -111,7 +101,7 @@ private static void standardDecrypt(final String kmsArn, final String fileName) // Decrypt with the KMS CMK and the escrow public key. You can use a combined provider, // as shown here, or just the KMS master key provider. - // 1. Instantiate the SDK + // 1. Instantiate the AWS Encryption SDK final AwsCrypto crypto = new AwsCrypto(); // 2. Instantiate a KMS master key provider @@ -141,7 +131,7 @@ private static void escrowDecrypt(final String fileName) throws Exception { // You can decrypt the stream using only the private key. // This method does not call KMS. - // 1. Instantiate the SDK + // 1. Instantiate the AWS Encryption SDK final AwsCrypto crypto = new AwsCrypto(); // 2. Instantiate a JCE master key provider diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java index 1b022bc5f..89098180a 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; import java.io.FileInputStream; @@ -59,7 +49,7 @@ public static void main(String[] args) throws IOException { // Create a JCE master key provider using the random key and an AES-GCM encryption algorithm JceMasterKey masterKey = JceMasterKey.getInstance(cryptoKey, "Example", "RandomKey", "AES/GCM/NoPadding"); - // Instantiate the SDK + // Instantiate the AWS Encryption SDK AwsCrypto crypto = new AwsCrypto(); // Create an encryption context to identify this ciphertext diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java index c1c662cb9..0ed0d209a 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java index 16817bfea..ba4d16cf3 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java index 4babf5c32..57f2716b2 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples.legacy; @@ -71,7 +61,7 @@ public static void main(final String[] args) { static byte[] encryptWithCaching(AwsKmsCmkId kmsCmkArn) { - // Instantiate the SDK + // Instantiate the AWS Encryption SDK final AwsCrypto crypto = new AwsCrypto(); // Create an encryption context diff --git a/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java b/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java index abbc7b4b1..26b9e3ee6 100644 --- a/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java +++ b/src/test/java/com/amazonaws/crypto/examples/ExamplesTest.java @@ -1,15 +1,5 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except - * in compliance with the License. A copy of the License is located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 package com.amazonaws.crypto.examples; From 619ad06e4b124a6c4b9aab308ff7ae7da3524189 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Mon, 23 Mar 2020 14:32:48 -0700 Subject: [PATCH 3/6] Adding periods --- .../examples/FileStreamingDefaults.java | 2 +- .../examples/InMemoryStreamingDefaults.java | 2 +- .../crypto/examples/OneStepDefaults.java | 4 +-- .../crypto/examples/OneStepUnsigned.java | 2 +- .../keyring/awskms/CustomClientSupplier.java | 4 +-- .../keyring/awskms/CustomKmsClientConfig.java | 4 +-- .../keyring/awskms/DiscoveryDecrypt.java | 4 +-- .../awskms/DiscoveryDecryptInRegionOnly.java | 4 +-- .../DiscoveryDecryptWithPreferredRegions.java | 4 +-- .../keyring/awskms/MultipleRegions.java | 4 +-- .../examples/keyring/awskms/SingleCmk.java | 4 +-- .../keyring/multi/AwsKmsWithEscrow.java | 2 +- .../examples/keyring/rawaes/RawAes.java | 4 +-- .../rawrsa/PublicPrivateKeySeparate.java | 4 +-- .../examples/keyring/rawrsa/RawRsa.java | 4 +-- .../legacy/BasicEncryptionExample.java | 12 ++++---- .../legacy/EscrowedEncryptExample.java | 28 +++++++++---------- .../examples/legacy/FileStreamingExample.java | 10 +++---- .../legacy/LambdaDecryptAndWriteExample.java | 6 ++-- .../MultiRegionRecordPusherExample.java | 8 +++--- .../legacy/SimpleDataKeyCachingExample.java | 12 ++++---- 21 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java index 10d9465d7..ae9b97e5f 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/FileStreamingDefaults.java @@ -43,7 +43,7 @@ public class FileStreamingDefaults { * @param sourcePlaintextFile Plaintext file to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final File sourcePlaintextFile) throws IOException { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // We assume that you can also write to the directory containing the plaintext file, diff --git a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java index 333dcc0e8..3757bc9b4 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java @@ -40,7 +40,7 @@ public class InMemoryStreamingDefaults { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) throws IOException { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java index c39afc022..a1adc744e 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java @@ -32,7 +32,7 @@ public class OneStepDefaults { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -55,7 +55,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // 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. diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java index 73def3d22..bbb38277d 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java @@ -69,7 +69,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // 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. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java index 8825fbf85..36bd3a632 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java @@ -85,7 +85,7 @@ public AWSKMS getClient(String regionId) { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -111,7 +111,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // 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. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java index 7acfcac54..b83926225 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java @@ -48,7 +48,7 @@ public class CustomKmsClientConfig { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -90,7 +90,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // 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. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java index 2393bd5f9..4752a8064 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java @@ -48,7 +48,7 @@ public class DiscoveryDecrypt { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -74,7 +74,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // Demonstrate that the ciphertext and plaintext are different. assert !Arrays.equals(ciphertext, sourcePlaintext); // Decrypt your encrypted data using the KMS discovery keyring. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java index 808ddf607..f08a314f8 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java @@ -55,7 +55,7 @@ public class DiscoveryDecryptInRegionOnly { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -90,7 +90,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // Demonstrate that the ciphertext and plaintext are different. assert !Arrays.equals(ciphertext, sourcePlaintext); // Decrypt your encrypted data using the KMS discovery keyring. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java index 2e0765f36..7ee1b0289 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java @@ -61,7 +61,7 @@ public class DiscoveryDecryptWithPreferredRegions { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -106,7 +106,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext .plaintext(sourcePlaintext).build()); final byte[] ciphertext = encryptResult.getResult(); - // Demonstrate that the ciphertext and plaintext are different + // Demonstrate that the ciphertext and plaintext are different. assert !Arrays.equals(ciphertext, sourcePlaintext); // Decrypt your encrypted data using the multi keyring. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java index 3eda20746..6ac169f3b 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java @@ -44,7 +44,7 @@ public class MultipleRegions { * @param sourcePlaintext Plaintext to encrypt */ public static void run(final AwsKmsCmkId awsKmsGeneratorCmk, final List awsKmsAdditionalCmks, byte[] sourcePlaintext) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto awsEncryptionSdk = new AwsCrypto(); // Prepare your encryption context. @@ -87,7 +87,7 @@ public static void run(final AwsKmsCmkId awsKmsGeneratorCmk, final List encryptionContext = Collections.singletonMap("ExampleContextKey", "ExampleContextValue"); - // 4. Encrypt the data + // 4. Encrypt the data. final CryptoResult encryptResult = crypto.encryptData(masterKeyProvider, EXAMPLE_DATA, encryptionContext); final byte[] ciphertext = encryptResult.getResult(); - // 5. Decrypt the data + // 5. Decrypt the data. final CryptoResult decryptResult = crypto.decryptData(masterKeyProvider, ciphertext); // 6. Before verifying the plaintext, verify that the customer master key that @@ -75,7 +75,7 @@ static void encryptAndDecrypt(final String keyArn) { throw new IllegalStateException("Wrong Encryption Context!"); } - // 8. Verify that the decrypted plaintext matches the original plaintext + // 8. Verify that the decrypted plaintext matches the original plaintext. assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA); } } diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java index e463704c9..39511249e 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java @@ -70,22 +70,22 @@ public static void main(final String[] args) throws Exception { private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception { // Encrypt with the KMS CMK and the escrowed public key - // 1. Instantiate the AWS Encryption SDK + // 1. Instantiate the AWS Encryption SDK. final AwsCrypto crypto = new AwsCrypto(); - // 2. Instantiate a KMS master key provider + // 2. Instantiate a KMS master key provider. final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn); - // 3. Instantiate a JCE master key provider + // 3. Instantiate a JCE master key provider. // Because the user does not have access to the private escrow key, // they pass in "null" for the private key parameter. final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); - // 4. Combine the providers into a single master key provider + // 4. Combine the providers into a single master key provider. final MasterKeyProvider provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub); - // 5. Encrypt the file + // 5. Encrypt the file. // To simplify the code, we omit the encryption context. Production code should always // use an encryption context. For an example, see the other SDK samples. final FileInputStream in = new FileInputStream(fileName); @@ -101,22 +101,22 @@ private static void standardDecrypt(final String kmsArn, final String fileName) // Decrypt with the KMS CMK and the escrow public key. You can use a combined provider, // as shown here, or just the KMS master key provider. - // 1. Instantiate the AWS Encryption SDK + // 1. Instantiate the AWS Encryption SDK. final AwsCrypto crypto = new AwsCrypto(); - // 2. Instantiate a KMS master key provider + // 2. Instantiate a KMS master key provider. final KmsMasterKeyProvider kms = new KmsMasterKeyProvider(kmsArn); - // 3. Instantiate a JCE master key provider + // 3. Instantiate a JCE master key provider. // Because the user does not have access to the private // escrow key, they pass in "null" for the private key parameter. final JceMasterKey escrowPub = JceMasterKey.getInstance(publicEscrowKey, null, "Escrow", "Escrow", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); - // 4. Combine the providers into a single master key provider + // 4. Combine the providers into a single master key provider. final MasterKeyProvider provider = MultipleProviderFactory.buildMultiProvider(kms, escrowPub); - // 5. Decrypt the file + // 5. Decrypt the file. // To simplify the code, we omit the encryption context. Production code should always // use an encryption context. For an example, see the other SDK samples. final FileInputStream in = new FileInputStream(fileName + ".encrypted"); @@ -131,15 +131,15 @@ private static void escrowDecrypt(final String fileName) throws Exception { // You can decrypt the stream using only the private key. // This method does not call KMS. - // 1. Instantiate the AWS Encryption SDK + // 1. Instantiate the AWS Encryption SDK. final AwsCrypto crypto = new AwsCrypto(); - // 2. Instantiate a JCE master key provider - // This method call uses the escrowed private key, not null + // 2. Instantiate a JCE master key provider. + // This method call uses the escrowed private key, not null. final JceMasterKey escrowPriv = JceMasterKey.getInstance(publicEscrowKey, privateEscrowKey, "Escrow", "Escrow", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); - // 3. Decrypt the file + // 3. Decrypt the file. // To simplify the code, we omit the encryption context. Production code should always // use an encryption context. For an example, see the other SDK samples. final FileInputStream in = new FileInputStream(fileName + ".encrypted"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java index 89098180a..050050972 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/FileStreamingExample.java @@ -43,16 +43,16 @@ public static void main(String[] args) throws IOException { srcFile = args[0]; // In this example, we generate a random key. In practice, - // you would get a key from an existing store + // you would get a key from an existing store. SecretKey cryptoKey = retrieveEncryptionKey(); - // Create a JCE master key provider using the random key and an AES-GCM encryption algorithm + // Create a JCE master key provider using the random key and an AES-GCM encryption algorithm. JceMasterKey masterKey = JceMasterKey.getInstance(cryptoKey, "Example", "RandomKey", "AES/GCM/NoPadding"); - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. AwsCrypto crypto = new AwsCrypto(); - // Create an encryption context to identify this ciphertext + // Create an encryption context to identify this ciphertext. Map context = Collections.singletonMap("Example", "FileStreaming"); // Because the file might be to large to load into memory, we stream the data, instead of @@ -73,7 +73,7 @@ public static void main(String[] args) throws IOException { throw new IllegalStateException("Bad encryption context"); } - // Return the plaintext data + // Return the plaintext data. out = new FileOutputStream(srcFile + ".decrypted"); IOUtils.copy(decryptingStream, out); decryptingStream.close(); diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java index 0ed0d209a..badadb3e0 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/LambdaDecryptAndWriteExample.java @@ -105,20 +105,20 @@ public Void handleRequest(KinesisEvent event, Context context) { ByteBuffer ciphertextBuffer = record.getKinesis().getData(); byte[] ciphertext = BinaryUtils.copyAllBytesFrom(ciphertextBuffer); - // Decrypt and unpack record + // Decrypt and unpack record. AwsCryptoResult plaintextResult = crypto_.decrypt( DecryptRequest.builder() .cryptoMaterialsManager(cachingMaterialsManager_) .ciphertext(ciphertext).build()); - // Verify the encryption context value + // Verify the encryption context value. String streamArn = record.getEventSourceARN(); String streamName = streamArn.substring(streamArn.indexOf("/") + 1); if (!streamName.equals(plaintextResult.getEncryptionContext().get("stream"))) { throw new IllegalStateException("Wrong Encryption Context!"); } - // Write record to DynamoDB + // Write record to DynamoDB. String jsonItem = new String(plaintextResult.getResult(), StandardCharsets.UTF_8); table_.putItem(Item.fromJSON(jsonItem)); } diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java index ba4d16cf3..a42e78ae1 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/MultiRegionRecordPusherExample.java @@ -51,7 +51,7 @@ public MultiRegionRecordPusherExample(final Region[] regions, final String kmsAl final DefaultAWSCredentialsProviderChain credentialsProvider = new DefaultAWSCredentialsProviderChain(); - // Build AwsKmsKeyring and AmazonKinesisClient objects for each target Region + // Build AwsKmsKeyring and AmazonKinesisClient objects for each target Region. final List keyrings = new ArrayList<>(); for (Region region : regions) { @@ -88,10 +88,10 @@ public void putRecord(final Map data) { String partitionKey = UUID.randomUUID().toString(); Map encryptionContext = Collections.singletonMap("stream", streamName_); - // JSON serialize data + // JSON serialize data. String jsonData = Jackson.toJsonString(data); - // Encrypt data + // Encrypt data. AwsCryptoResult result = crypto_.encrypt( EncryptRequest.builder() .cryptoMaterialsManager(cachingMaterialsManager_) @@ -101,7 +101,7 @@ public void putRecord(final Map data) { byte[] encryptedData = result.getResult(); - // Put records to Kinesis stream in all Regions + // Put records to Kinesis stream in all Regions. for (AmazonKinesis regionalKinesisClient : kinesisClients_) { regionalKinesisClient.putRecord( streamName_, diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java index 57f2716b2..90ac05335 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/SimpleDataKeyCachingExample.java @@ -61,19 +61,19 @@ public static void main(final String[] args) { static byte[] encryptWithCaching(AwsKmsCmkId kmsCmkArn) { - // Instantiate the AWS Encryption SDK + // Instantiate the AWS Encryption SDK. final AwsCrypto crypto = new AwsCrypto(); - // Create an encryption context + // Create an encryption context. final Map encryptionContext = Collections.singletonMap("purpose", "test"); - // Create a keyring + // Create a keyring. final Keyring keyring = StandardKeyrings.awsKms(kmsCmkArn); - // Create a cache + // Create a cache. final CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(CAPACITY); - // Create a caching CMM + // Create a caching CMM. final CryptoMaterialsManager cachingCmm = CachingCryptoMaterialsManager.newBuilder() .withKeyring(keyring) @@ -83,7 +83,7 @@ static byte[] encryptWithCaching(AwsKmsCmkId kmsCmkArn) { .build(); // When the call to encrypt specifies a caching CMM, - // the encryption operation uses the data key cache + // the encryption operation uses the data key cache. return crypto.encrypt(EncryptRequest.builder() .cryptoMaterialsManager(cachingCmm) .plaintext(EXAMPLE_DATA) From 66e8dabb438040223f99019bb583b8a253644fd6 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Mon, 23 Mar 2020 15:40:25 -0700 Subject: [PATCH 4/6] Adding NIST recommendation for RSA --- .../keyring/awskms/DiscoveryDecryptWithPreferredRegions.java | 4 ++-- .../crypto/examples/keyring/awskms/MultipleRegions.java | 2 +- .../crypto/examples/keyring/multi/AwsKmsWithEscrow.java | 4 +++- .../examples/keyring/rawrsa/PublicPrivateKeySeparate.java | 4 +++- .../com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java | 4 +++- .../crypto/examples/legacy/EscrowedEncryptExample.java | 4 +++- 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java index 7ee1b0289..3622774ff 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java @@ -92,7 +92,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Finally, combine those two keyrings into a multi-keyring. // - // The multi-keyring steps through its member keyrings in the order that you provider them, + // The multi-keyring steps through its member keyrings in the order that you provide them, // attempting to decrypt every encrypted data key with each keyring before moving on to the next keyring. // Because of this, otherRegionsDecryptKeyring will not be called // unless localRegionDecryptKeyring fails to decrypt every encrypted data key. @@ -109,7 +109,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Demonstrate that the ciphertext and plaintext are different. assert !Arrays.equals(ciphertext, sourcePlaintext); - // Decrypt your encrypted data using the multi keyring. + // Decrypt your encrypted data using the multi-keyring. // // We do not need to specify the encryption context on decrypt // because the header message includes the encryption context. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java index 6ac169f3b..3a2cb7b64 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java @@ -37,7 +37,7 @@ public class MultipleRegions { /** - * Demonstrate an encrypt/decrypt cycle using a KMS keyring with a single CMK. + * Demonstrate an encrypt/decrypt cycle using a KMS keyring with CMKs in multiple regions. * * @param awsKmsGeneratorCmk The ARN of an AWS KMS CMK that protects data keys * @param awsKmsAdditionalCmks Additional ARNs of secondary KMS CMKs diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java index cf277ab33..85a2828ba 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java @@ -62,7 +62,9 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Generate an RSA key pair to use with your keyring. // In practice, you should get this key from a secure key management system such as an HSM. final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); // Escrow keys should be very strong + // The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. + // https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths + kg.initialize(4096); final KeyPair keyPair = kg.generateKeyPair(); // Create the encrypt keyring that only has access to the public key. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java index 4b8118e6e..604bee5b0 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java @@ -58,7 +58,9 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep // Generate an RSA key pair to use with your keyring. // In practice, you should get this key from a secure key management system such as an HSM. final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); // Escrow keys should be very strong + // The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. + // https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths + kg.initialize(4096); final KeyPair keyPair = kg.generateKeyPair(); // Create the keyring that determines how your data keys are protected. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java index 04b260a2c..6af3704b8 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java @@ -48,7 +48,9 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep // Generate an RSA key pair to use with your keyring. // In practice, you should get this key from a secure key management system such as an HSM. final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); // Escrow keys should be very strong + // The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. + // https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths + kg.initialize(4096); final KeyPair keyPair = kg.generateKeyPair(); // Create the keyring that determines how your data keys are protected. diff --git a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java index 39511249e..18286624f 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java +++ b/src/examples/java/com/amazonaws/crypto/examples/legacy/EscrowedEncryptExample.java @@ -153,7 +153,9 @@ private static void escrowDecrypt(final String fileName) throws Exception { private static void generateEscrowKeyPair() throws GeneralSecurityException { final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); - kg.initialize(4096); // Escrow keys should be very strong + // The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. + // https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths + kg.initialize(4096); final KeyPair keyPair = kg.generateKeyPair(); publicEscrowKey = keyPair.getPublic(); privateEscrowKey = keyPair.getPrivate(); From ada84e81f7c04378d8fab33f1d68767d0fb6fb06 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Tue, 24 Mar 2020 11:54:01 -0700 Subject: [PATCH 5/6] Adding example for DER formatted RSA keys --- src/examples/README.md | 8 +- .../examples/keyring/rawaes/RawAes.java | 2 +- .../rawrsa/PublicPrivateKeySeparate.java | 9 +- .../examples/keyring/rawrsa/RawRsa.java | 5 +- .../keyring/rawrsa/RawRsaDerEncoded.java | 134 ++++++++++++++++++ 5 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java diff --git a/src/examples/README.md b/src/examples/README.md index afe262e49..a20084cf0 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -21,9 +21,9 @@ you need to describe how you want the library to protect your data keys. You can do this using [keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers), or using [master key providers](#master-key-providers). -These examples will show you how yo use the configuration tools that we include for you -as well as how to create some of your own. We start with AWS KMS examples, then show -how to use other wrapping keys. +These examples will show you how to use the configuration tools that we include for you +as well as how to create some of your own. +We start with AWS KMS examples, then show how to use other wrapping keys. * Using AWS Key Management Service (AWS KMS) * How to use a single AWS KMS CMK @@ -43,6 +43,8 @@ how to use other wrapping keys. * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java) * How to encrypt with a raw RSA public key wrapping key without access to the private key * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java) + * How to use a raw RSA wrapping key when the key is DER encoded + * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java) * Combining wrapping keys * How to combine AWS KMS with an offline escrow key * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java index 6a6e3b90e..b39483a48 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java @@ -48,7 +48,7 @@ public static void run(final byte[] sourcePlaintext) { // // 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[16]; // 128 bits + byte[] rawKey = new byte[32]; // 256 bits rnd.nextBytes(rawKey); SecretKey key = new SecretKeySpec(rawKey, "AES"); diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java index 604bee5b0..2d9ea9221 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java @@ -22,7 +22,7 @@ /** * One of the benefits of asymmetric encryption * is that you can encrypt with just the public key. - * This means that you give someone the ability to encrypt + * This means that you can give someone the ability to encrypt * without giving them the ability to decrypt. *

* The raw RSA keyring supports encrypt-only operations @@ -31,7 +31,10 @@ * This example shows how to construct and use the raw RSA keyring * to encrypt with only the public key and decrypt with the private key. *

- * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring + * If your RSA key is in DER format, + * see the {@link RawRsaDerEncoded} example. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring *

* In this example, we use the one-step encrypt and decrypt APIs. */ @@ -113,7 +116,7 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep .keyring(publicKeyKeyring) .ciphertext(ciphertext) .build()); - assert false; + throw new AssertionError("The public key can never decrypt!"); } catch (AwsCryptoException ex) { // The public key cannot decrypt. // Reaching this point means everything is working as expected. diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java index 6af3704b8..a37caea2f 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java @@ -21,7 +21,10 @@ /** * This examples shows how to configure and use a raw RSA keyring using a pre-loaded RSA key pair. *

- * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-aes-keyring + * If your RSA key is in DER format, + * see the {@link RawRsaDerEncoded} example. + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring *

* In this example, we use the one-step encrypt and decrypt APIs. */ diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java new file mode 100644 index 000000000..3e8997661 --- /dev/null +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java @@ -0,0 +1,134 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.amazonaws.crypto.examples.keyring.rawrsa; + +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.RawRsaKeyringBuilder; +import com.amazonaws.encryptionsdk.keyrings.StandardKeyrings; + +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * When you store RSA keys, you have to serialize them somehow. + *

+ * This example shows how to configure and use a raw RSA keyring using a DER-encoded RSA private key. + *

+ * The most commonly used encodings for RSA keys tend to be PEM and DER. + * For parsing PEM-encoded keys, see https://www.bouncycastle.org/docs/pkixdocs1.4/org/bouncycastle/openssl/PEMParser.html + *

+ * https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html#use-raw-rsa-keyring + *

+ * In this example, we use the one-step encrypt and decrypt APIs. + */ +public class RawRsaDerEncoded { + + /** + * Demonstrate an encrypt/decrypt cycle using a raw RSA keyring loaded from a DER-encoded key. + * + * @param sourcePlaintext Plaintext to encrypt + */ + public static void run(final byte[] sourcePlaintext) throws GeneralSecurityException { + // 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 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 RSA key pair to use with your keyring. + // In practice, you should get this key from a secure key management system such as an HSM. + final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); + // The National Institute of Standards and Technology (NIST) recommends a minimum of 2048-bit keys for RSA. + // https://www.nist.gov/publications/transitioning-use-cryptographic-algorithms-and-key-lengths + kg.initialize(4096); + final KeyPair keyPair = kg.generateKeyPair(); + + // Serialize the RSA keys to DER encoding. + // This or PEM encoding is likely to be what you get from your key management system in practice. + byte[] publicKeyEncoded = keyPair.getPublic().getEncoded(); + byte[] privateKeyEncoded = keyPair.getPrivate().getEncoded(); + + final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + // Deserialize the RSA private key. + final PrivateKey privateKey = keyFactory.generatePrivate( + new PKCS8EncodedKeySpec(privateKeyEncoded)); + + // Deserialize the RSA public key. + final PublicKey publicKey = keyFactory.generatePublic( + new X509EncodedKeySpec(publicKeyEncoded)); + + // Create the keyring that determines how your data keys are protected. + final Keyring keyring = StandardKeyrings.rawRsaBuilder() + // The key namespace and key name are defined by you + // and are used by the raw RSA 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-rsa-keyring + .keyNamespace("some managed raw keys") + .keyName("my RSA wrapping key") + .privateKey(privateKey) + .publicKey(publicKey) + // The padding scheme tells the raw RSA keyring + // how to use your wrapping key to encrypt data keys. + // + // We recommend using OAEP_SHA256_MGF1. + // You should not use PKCS1 unless you require it for backwards compatibility. + .paddingScheme(RawRsaKeyringBuilder.RsaPaddingScheme.OAEP_SHA256_MGF1) + .build(); + + // Encrypt your plaintext data. + final AwsCryptoResult 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. + // + // We do not need to specify the encryption context on decrypt + // because the header message includes the encryption context. + final AwsCryptoResult 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)); + }); + } +} From 3436adf2d482fad2b671bc75e79bcd0a76d91522 Mon Sep 17 00:00:00 2001 From: Wesley Rosenblum Date: Wed, 25 Mar 2020 10:41:58 -0700 Subject: [PATCH 6/6] Wording changes based on feedback --- src/examples/README.md | 10 +++++----- .../crypto/examples/InMemoryStreamingDefaults.java | 4 ++-- .../amazonaws/crypto/examples/OneStepDefaults.java | 4 ++-- .../amazonaws/crypto/examples/OneStepUnsigned.java | 4 ++-- .../keyring/awskms/CustomClientSupplier.java | 8 ++++---- .../keyring/awskms/CustomKmsClientConfig.java | 12 ++++++------ .../examples/keyring/awskms/DiscoveryDecrypt.java | 12 ++++++------ .../keyring/awskms/DiscoveryDecryptInRegionOnly.java | 12 ++++++------ .../awskms/DiscoveryDecryptWithPreferredRegions.java | 4 ++-- .../examples/keyring/awskms/MultipleRegions.java | 4 ++-- .../crypto/examples/keyring/awskms/SingleCmk.java | 4 ++-- .../examples/keyring/multi/AwsKmsWithEscrow.java | 4 ++-- .../crypto/examples/keyring/rawaes/RawAes.java | 4 ++-- .../keyring/rawrsa/PublicPrivateKeySeparate.java | 4 ++-- .../crypto/examples/keyring/rawrsa/RawRsa.java | 4 ++-- .../examples/keyring/rawrsa/RawRsaDerEncoded.java | 4 ++-- 16 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/examples/README.md b/src/examples/README.md index a20084cf0..b6e778219 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -16,17 +16,17 @@ in the [`examples`](./java/com/amazonaws/crypto/examples) directory. ## Configuration -To use the library APIs, +To use the encryption and decryption APIs, you need to describe how you want the library to protect your data keys. -You can do this using +You can do this by configuring [keyrings](#keyrings) or [cryptographic materials managers](#cryptographic-materials-managers), -or using [master key providers](#master-key-providers). +or by configuring [master key providers](#master-key-providers). These examples will show you how to use the configuration tools that we include for you -as well as how to create some of your own. +and how to create some of your own. We start with AWS KMS examples, then show how to use other wrapping keys. * Using AWS Key Management Service (AWS KMS) - * How to use a single AWS KMS CMK + * How to use one AWS KMS CMK * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java) * How to use multiple AWS KMS CMKs in different regions * [with keyrings](./java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java) diff --git a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java index 3757bc9b4..94586f7a6 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/InMemoryStreamingDefaults.java @@ -73,8 +73,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoInputStream decryptingStream = awsEncryptionSdk.createDecryptingInputStream( CreateDecryptingInputStreamRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java index a1adc744e..5a9c4bc13 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepDefaults.java @@ -60,8 +60,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java index bbb38277d..5d457d2f3 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java +++ b/src/examples/java/com/amazonaws/crypto/examples/OneStepUnsigned.java @@ -74,8 +74,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java index 36bd3a632..0e6ddcdf5 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomClientSupplier.java @@ -24,8 +24,8 @@ * supplies a client with the same configuration for every region. * If you need different behavior, you can write your own client supplier. *

- * One use-case where you might need this is - * if you need different credentials to talk to different AWS regions. + * You might use this + * if you need different credentials in different AWS regions. * This might be because you are crossing partitions (ex: "aws" and "aws-cn") * or if you are working with regions that have separate authentication silos * like "ap-east-1" and "me-south-1". @@ -116,8 +116,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java index b83926225..fd3af280d 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/CustomKmsClientConfig.java @@ -20,10 +20,10 @@ import java.util.Map; /** - * By default, the KMS keyring will use the default configurations - * for all KMS clients and will use the default discoverable credentials. - * If you need to change these configurations, - * you can do that using the client supplier. + * By default, the KMS keyring uses the default configurations + * for all KMS clients and uses the default discoverable credentials. + * If you need to change this configuration, + * you can configure the client supplier. *

* This example shows how to use custom-configured clients with the KMS keyring. *

@@ -95,8 +95,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java index 4752a8064..64b031887 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecrypt.java @@ -19,10 +19,10 @@ * 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. + * especially when you don't know which CMKs were 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. + * The KMS discovery keyring does nothing on encrypt + * but attempts to decrypt *any* data keys that were encrypted under a KMS CMK. *

* This example shows how to configure and use a KMS discovery keyring. *

@@ -63,7 +63,7 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // 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. + // Create a KMS discovery keyring to use on decrypt. final Keyring decryptKeyring = StandardKeyrings.awsKmsDiscoveryBuilder().build(); // Encrypt your plaintext data. @@ -79,8 +79,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] 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. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(decryptKeyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java index f08a314f8..ad545cbec 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptInRegionOnly.java @@ -23,13 +23,13 @@ * 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. + * especially if you don't know 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. + * The KMS discovery keyring does nothing on encrypt + * but attempts to decrypt *any* data keys that were encrypted under a KMS CMK. *

* However, sometimes you need to be a *bit* more restrictive than that. - * To address this need, you can use a client supplier to restrict what regions a KMS keyring can talk to. + * To address this need, you can use a client supplier that restricts the regions a KMS keyring can talk to. *

* This example shows how to configure and use a KMS regional discovery keyring that is restricted to one region. *

@@ -95,8 +95,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] 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. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(decryptKeyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java index 3622774ff..5068395d2 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/DiscoveryDecryptWithPreferredRegions.java @@ -111,8 +111,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the multi-keyring. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(decryptKeyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java index 3a2cb7b64..8eabf06c6 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/MultipleRegions.java @@ -92,8 +92,8 @@ public static void run(final AwsKmsCmkId awsKmsGeneratorCmk, final List decryptResult1 = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(singleCmkKeyringThatGenerated) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java index 511cae7f3..b77824e83 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/awskms/SingleCmk.java @@ -69,8 +69,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java index 85a2828ba..541c017cb 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/multi/AwsKmsWithEscrow.java @@ -119,8 +119,8 @@ public static void run(final AwsKmsCmkId awsKmsCmk, final byte[] sourcePlaintext // Decrypt your encrypted data separately using the KMS keyring and the escrow decrypt keyring. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptedKmsResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(kmsKeyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java index b39483a48..9d79f7440 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawaes/RawAes.java @@ -78,8 +78,8 @@ public static void run(final byte[] sourcePlaintext) { // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java index 2d9ea9221..0bc31b191 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/PublicPrivateKeySeparate.java @@ -124,8 +124,8 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep // Decrypt your encrypted data using the decrypt keyring. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(privateKeyKeyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java index a37caea2f..3ca0a6c0e 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsa.java @@ -89,8 +89,8 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring) diff --git a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java index 3e8997661..c74c80495 100644 --- a/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java +++ b/src/examples/java/com/amazonaws/crypto/examples/keyring/rawrsa/RawRsaDerEncoded.java @@ -111,8 +111,8 @@ public static void run(final byte[] sourcePlaintext) throws GeneralSecurityExcep // Decrypt your encrypted data using the same keyring you used on encrypt. // - // We do not need to specify the encryption context on decrypt - // because the header message includes the encryption context. + // You do not need to specify the encryption context on decrypt because + // the header of the encrypted message includes the encryption context. final AwsCryptoResult decryptResult = awsEncryptionSdk.decrypt( DecryptRequest.builder() .keyring(keyring)