AWS Encryption SDK Developer Guide
encryption-sdk-developer-guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 78
Download | |
Open PDF In Browser | View PDF |
AWS Encryption SDK Developer Guide AWS Encryption SDK Developer Guide AWS Encryption SDK: Developer Guide Copyright © 2017 Amazon Web Services, Inc. and/or its affiliates. All rights reserved. Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. All other trademarks not owned by Amazon are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by Amazon. AWS Encryption SDK Developer Guide Table of Contents What Is the AWS Encryption SDK? ....................................................................................................... 1 Where to find more information .................................................................................................. 2 How the SDK Works ................................................................................................................... 2 Symmetric Key Encryption .................................................................................................. 2 Envelope Encryption ........................................................................................................... 3 AWS Encryption SDK Encryption Workflows .......................................................................... 4 Concepts ................................................................................................................................... 5 Data Keys .......................................................................................................................... 6 Master key ........................................................................................................................ 6 Master key operations: Generate, Encrypt, Decrypt ................................................................. 6 Master key provider ............................................................................................................ 7 Cryptographic Materials Manager ......................................................................................... 7 Algorithm Suite ................................................................................................................. 7 Encryption Context ............................................................................................................. 8 Encrypted Message ............................................................................................................. 8 Getting Started .................................................................................................................................. 9 Supported Algorithm Suites .............................................................................................................. 11 Recommended: AES-GCM with Key Derivation and Signing ............................................................ 11 Other Supported Algorithm Suites ............................................................................................. 12 Programming Languages ................................................................................................................... 13 Java ........................................................................................................................................ 13 Prerequisites .................................................................................................................... 13 Installation ...................................................................................................................... 14 Example Code .................................................................................................................. 14 Python .................................................................................................................................... 21 Prerequisites .................................................................................................................... 21 Installation ...................................................................................................................... 22 Example Code .................................................................................................................. 22 Data Key Caching ............................................................................................................................. 29 How to Implement Data Key Caching ......................................................................................... 30 Implement Data Key Caching: Step-by-Step ......................................................................... 30 Data Key Caching Example: Encrypt a String ........................................................................ 32 Setting Cache Security Thresholds .............................................................................................. 34 Data Key Caching Details .......................................................................................................... 36 How Data Key Caching Works ............................................................................................ 36 Creating a Cryptographic Materials Cache ............................................................................ 38 Creating a Caching Cryptographic Materials Manager ............................................................ 39 What Is in a Data Key Cache Entry? .................................................................................... 39 Encryption Context: How to Select Cache Entries ................................................................. 40 Data Key Caching Example ........................................................................................................ 40 LocalCryptoMaterialsCache Results ..................................................................................... 41 Java Example ................................................................................................................... 42 Python Example ............................................................................................................... 46 AWS CloudFormation Template .......................................................................................... 49 Frequently Asked Questions ............................................................................................................... 53 Reference ........................................................................................................................................ 56 Message Format Reference ........................................................................................................ 56 Header Structure .............................................................................................................. 57 Body Structure ................................................................................................................. 61 Footer Structure ............................................................................................................... 63 Body AAD Reference ................................................................................................................. 64 Message Format Examples ......................................................................................................... 65 Non-Framed Data ............................................................................................................. 65 Framed Data .................................................................................................................... 67 iii AWS Encryption SDK Developer Guide Algorithms Reference ................................................................................................................ 70 Initialization Vector Reference .................................................................................................... 72 Document History ............................................................................................................................ 73 iv AWS Encryption SDK Developer Guide What Is the AWS Encryption SDK? The AWS Encryption SDK is an encryption library that helps make it easier for you to implement encryption best practices in your application. It enables you to focus on the core functionality of your application, rather than on how to best encrypt and decrypt your data. The Encryption SDK answers questions like the following for you: • Which encryption algorithm should I use? • How, or in which mode, should I use that algorithm? • How do I generate the encryption key? • How do I protect the encryption key, and where should I store it? • How can I make my encrypted data portable? • How do I ensure that the intended recipient can read my encrypted data? • How can I ensure my encrypted data is not modified between the time it is written and when it is read? Without the AWS Encryption SDK, you might spend more effort on building an encryption solution than on the core functionality of your application. The AWS Encryption SDK answers these questions by providing the following things. A Default Implementation that Adheres to Cryptography Best Practices By default, the AWS Encryption SDK generates a unique data key for each data object that it encrypts. This follows the cryptography best practice of using unique data keys for each encryption operation. The Encryption SDK encrypts your data using a secure, authenticated, symmetric key algorithm. For more information, see Supported Algorithm Suites (p. 11). A Framework for Protecting Data Keys with Master Keys The AWS Encryption SDK protects the data keys that encrypt your data by encrypting them under one or more master keys. By providing a framework to encrypt data keys with more than one master key, the Encryption SDK helps make your encrypted data portable. For example, you can encrypt data under multiple AWS Key Management Service (AWS KMS) customer master keys (CMKs), each in a different AWS Region. Then you can copy the encrypted data to any of the regions and use the CMK in that region to decrypt it. You can also encrypt data under a CMK in AWS KMS and a master key in an on-premises HSM, enabling you to later decrypt the data even if one of the options is unavailable. 1 AWS Encryption SDK Developer Guide Where to find more information A Formatted Message that Stores Encrypted Data Keys with the Encrypted Data The AWS Encryption SDK stores the encrypted data and encrypted data key together in an encrypted message (p. 8) that uses a defined data format. This means you don't need to keep track of or protect the data keys that encrypt your data because the Encryption SDK does it for you. With the AWS Encryption SDK, you define a master key provider (p. 7) that returns one or more master keys (p. 6). Then you encrypt and decrypt your data using straightforward methods provided by the Encryption SDK. The Encryption SDK does the rest. Where to find more information If you're looking for more information about the AWS Encryption SDK and client-side encryption, try these sources. • To get started quickly, see Getting Started (p. 9). • For more information about how this SDK works, see How the SDK Works (p. 2). • For help with the terms and concepts used in this SDK, see Concepts in the AWS Encryption SDK (p. 5). • For detailed technical information, see the Reference (p. 56). • For information about the Java implementation of the AWS Encryption SDK, see AWS Encryption SDK for Java (p. 13), the Encryption SDK Javadocs, and the aws-encryption-sdk-java GitHub repository. • For information about the Python implementation of the AWS Encryption SDK, see AWS Encryption SDK for Python (p. 21), the Encryption SDK Python documentation, and the aws-encryption-sdkpython GitHub repository. • For help with questions about using the Encryption SDK, read and post on the AWS Key Management Service (KMS) Discussion Forum that the Encryption SDK shares with KMS. • If you have questions or comments about this guide, let us know! Use the feedback links in the lower right corner of this page. The AWS Encryption SDK is provided for free under the Apache license. How the AWS Encryption SDK Works The AWS Encryption SDK uses envelope encryption to protect your data and the corresponding data keys. For more information, see the following topics. Topics • Symmetric Key Encryption (p. 2) • Envelope Encryption (p. 3) • AWS Encryption SDK Encryption Workflows (p. 4) Symmetric Key Encryption To encrypt data, the AWS Encryption SDK provides raw data, known as plaintext data, and a data key to an encryption algorithm. The encryption algorithm uses those inputs to encrypt the data. Then, the Encryption SDK returns an encrypted message (p. 8) that includes the encrypted data and an encrypted copy of the data key. 2 AWS Encryption SDK Developer Guide Envelope Encryption To decrypt the encrypted message, the Encryption SDK provides the encrypted message to a decryption algorithm that uses those inputs to return the plaintext data. Because the same data key is used to encrypt and decrypt the data, the operations are known as symmetric key encryption and decryption. The following figure shows symmetric key encryption and decryption in the AWS Encryption SDK. Envelope Encryption The security of your encrypted data depends on protecting the data key that can decrypt it. One accepted best practice for protecting the data key is to encrypt it. To do this, you need another encryption key, known as a master key (p. 6). This practice of using a master key to encrypt data keys is known as envelope encryption. Some of the benefits of envelope encryption include the following. Protecting Data Keys When you encrypt a data key, you don't have to worry about where to store it because the data key is inherently protected by encryption. You can safely store the encrypted data key with the encrypted data. The AWS Encryption SDK does this for you. It saves the encrypted data and the encrypted data key together in an encrypted message (p. 8). Encrypting the Same Data Under Multiple Master Keys Encryption operations can be time-consuming, particularly when the data being encrypted are large objects. Instead of reencrypting raw data multiple times with different keys, you can reencrypt only the data keys that protect the raw data. Combining the Strengths of Multiple Algorithms In general, symmetric key encryption algorithms are faster and produce smaller ciphertexts than assymetric or public key encryption. But, public key algorithms provide inherent separation of roles and easier key management. You might want to combine the strengths of each. For example, you might encrypt raw data with symmetric key encryption, and then encrypt the data key with public key encryption. The AWS Encryption SDK uses envelope encryption. It encrypts your data with a data key. Then, it encryptes the data key with a master key. The Encryption SDK returns the encrypted data and the encrypted data keys in a single encrypted message, as shown in the following diagram. 3 AWS Encryption SDK Developer Guide AWS Encryption SDK Encryption Workflows If you have multiple master keys, each of them can encrypt the plaintext data key. Then, the Encryption SDK returns an encrypted message that contains the encrypted data and the collection of encrypted data keys. Any one of the master keys can decrypt one of the encrypted data keys, which can then decrypt the data. When you use envelope encryption, you must protect your master keys from unauthorized access. You can do this in one of the following ways: • Use a web service designed for this purpose, such as AWS Key Management Service (AWS KMS). • Use a hardware security module (HSM) such as those offered by AWS CloudHSM. • Use your existing key management tools. If you don't have a key management system, we recommend AWS KMS. The AWS Encryption SDK integrates with AWS KMS to help you protect and use your master keys. You can also use the AWS Encryption SDK with other master key providers, including custom ones that you define. Even if you don't use AWS, you can still use this Encryption SDK. AWS Encryption SDK Encryption Workflows The workflows in this section explain how the SDK encrypts data and decrypts encrypted messages (p. 8). They show how the SDK uses the components that you create, including the cryptographic materials manager (p. 7) (CMM), master key provider (p. 7), and master key (p. 6), to respond to encryption and decryption requests from your application. How the SDK Encrypts Data The SDK provides methods that encrypt strings, byte arrays, and byte streams. For code examples showing calls to encrypt and decrypt strings and byte streams in each supported programming languages, see the examples in the Programming Languages (p. 13) section. 1. Your application passes plaintext data to one of the encryption methods. To indicate the source of the data keys (p. 6) that you want to use to encrypt your data, your request specifies a cryptographic materials manager (CMM) or a master key provider. (If you specify a master key provider, the Encryption SDK creates a default CMM that interacts with your chosen master key provider.) 2. The encryption method asks the CMM for data keys (and related cryptographic material). 4 AWS Encryption SDK Developer Guide Concepts 3. The CMM gets a master key (p. 6) from its master key provider. Note If you are using AWS Key Management Service (AWS KMS), the KMS master key object that is returned identifies the CMK, but the actual CMK never leaves the AWS KMS service. 4. The CMM asks the master key to generate a data key. The master key returns two copies of the data key, one in plaintext and one encrypted under the master key. 5. The CMM returns the plaintext and encrypted data keys to the encryption method. 6. The encryption method uses the plaintext data key to encrypt the data, and then discards the plaintext data key. 7. The encryption method returns an encrypted message (p. 8) that contains the encrypted data and the encrypted data key. How the SDK Decrypts an Encrypted Message The SDK provides methods that decrypt an encrypted message and return plaintext strings, byte arrays, or byte streams. For code examples in each supported programming languages, see the examples in the Programming Languages (p. 13) section. 1. Your application passes an encrypted message to a decryption method. To indicate the source of the data keys (p. 6) that were used to encrypt your data, your request specifies a cryptographic materials manager (CMM) or a master key provider. (If you specify a master key provider, the Encryption SDK creates a default CMM that interacts with the specified master key provider.) 2. The decryption method extracts the encrypted data key from the encrypted message. Then, it asks the cryptographic materials manager (CMM) for a data key to decrypt the encrypted data key. 3. The CMM asks its master key provider for a master key that can decrypt the encrypted data key. 4. The CMM uses the master key to decrypt the encrypted data key. Then, it returns the plaintext data key to the decryption method. 5. The decryption method uses the plaintext data key to decrypt the data, then discards the plaintext data key. 6. The decryption method returns the plaintext data. Concepts in the AWS Encryption SDK This section introduces the concepts used in the AWS Encryption SDK. The Encryption SDK is designed so that you can use the default implementations of the components without detailed knowledge about their functionality. This section is provided as a glossary and reference. Topics • Data Keys (p. 6) • Master key (p. 6) • Master key operations: Generate, Encrypt, Decrypt (p. 6) • Master key provider (p. 7) • Cryptographic Materials Manager (p. 7) • Algorithm Suite (p. 7) • Encryption Context (p. 8) • Encrypted Message (p. 8) 5 AWS Encryption SDK Developer Guide Data Keys Data Keys A data key consists of cryptographic material. It is the secret key that protects the data that you encrypt. Data keys are generated by master keys (p. 6). You do not need to implement or extend data keys to use the AWS Encryption SDK. When a master key generates a data key, it returns two copies of the data key; one in plaintext and one that is encrypted by the master key that generated it. The plaintext data key can be encrypted by multiple master keys, each of which returns an encrypted copy of the data key. Every encrypted data key is associated with the master key that encrypted it and the master key provider (p. 7) that supplied the master key. When you encrypt data in the AWS Encryption SDK, the encrypted data keys are stored in an encrypted message (p. 8) along with the encrypted data. In the Encryption SDK, we distinguish data keys from data encryption keys. Several of the supported algorithm suites (p. 7), including the default suite, use a key derivation function that prevents the data key from hitting its cryptographic limits. The key derivation function takes the data key as input and returns a data encryption key that is actually used to encrypt the data. For this reason, we often say that data is encrypted "under" a data key rather than "by" the data key. Master key A master key encrypts, decrypts, and generates data keys (p. 2). The AWS Encryption SDK represents master keys as abstract classes or interfaces so you can implement the master key operations in the way that best meets the security requirements of your organization. For example, although they are called "keys," master keys might not have their own cryptographic material. Also, unlike data keys, whose use and algorithm suite (p. 7) are strictly defined by AWS Encryption SDK, master keys can use any algorithm suite or implementation. Master keys are instrumental to envelope encryption (p. 3). In envelope encryption, one master key generates and encrypts a data key that is used to encrypt data. Other master keys then re-encrypt the plaintext data key. As a result, any master key is sufficient to decrypt the data. Each master key is associated with one master key provider (p. 7) that returns one or more master keys to the caller. The AWS Encryption SDK provides several commonly used master keys, such as AWS Key Management Service (AWS KMS) customer master keys (CMKs), raw AES-GCM (Advanced Encryption Standard / Galois Counter Mode) keys, and RSA keys. You can implement your own master keys for other cryptographic algorithms and services. For example, you could implement master keys backed by implementations of Elliptical Curve Integrated Encryption Scheme (ECIES), Key Management Interoperability Program (KMIP), tokenization services, or other proprietary systems. Master key operations: Generate, Encrypt, Decrypt Master keys in the AWS Encryption SDK generate, encrypt, and decrypt data keys (p. 6). You write methods to perform these operations when you create a master key, but your application does not call the methods directly. The SDK calls them when you ask it to encrypt or decrypt data. You can implement the master key methods in the way that works best for your organization. For example, when asked to generate a data key, a master key can create or return a key in any way that fulfills the requirements of the algorithm suite that they use. Master keys can generate data keys locally or remotely. They can derive the keys algorithmically, call a service that generates the cryptographic material, or return previously-generated data keys. The SDK requires only that they return a valid data key object. 6 AWS Encryption SDK Developer Guide Master key provider Also, although master keys must implement all three methods, you can create master keys that actually perform only one or two of the three operations. Calls to the remaining methods just fail or return errors. These limited master keys might be useful in a system with strict access controls that do not let the same users encrypt and decrypt data. All master key operations take an encryption context (p. 8) as input. For optimal security, master key operations that encrypt data keys should cryptographically bind the encryption context to the encrypted data so that changing any key or value in the encryption context invalidates the encryption. Master key operations that decrypt should verify the encryption context and fail unless they include the same encryption context used to encrypt. The encryption context is most useful when there are users who have permission to decrypt, but not encrypt. Master key provider A master key provider returns objects that represent master keys. Each master key is associated with one master key provider, but a master key provider typically provides multiple master keys. The simplest master key provider always returns the same master key (p. 6). In fact, master keys are implemented as master keys providers that only return themselves. More complex master key providers might use key rotation, the encryption context, application permissions, and other factors to select master keys from among the set they can provide. Many master keys providers wrap or extend other master key providers to customize their behavior and functionality. For example, a custom master key provider might select a master key provider from a collection, delegate requests, and combine their results. Cryptographic Materials Manager The cryptographic materials manager (CMM) gets the cryptographic materials that are used to encrypt and decrypt data. The cryptographic materials include plaintext and encrypted data keys, and an optional message signing key. You can use the Default CMM that the AWS Encryption SDK provides (DefaultCryptoMaterialsManager) or write a custom CMM. Each Default CMM is associated with a master key provider (p. 7). When it gets a materials request, the Default CMM gets master keys from its master key provider and uses them to generate the requested cryptographic material. This might involve a call to a cryptographic service, such as AWS Key Management Service (AWS KMS). In each call to encrypt or decrypt data, you specify a CMM or a master key provider. This lets you choose a particular set of master keys for the operation. You can create a CMM explicitly and specify its master key provider, but that is not required. If you specify a master key provider in an encryption request, the SDK creates a Default CMM for the master key provider. Because the CMM acts as a liaison between the SDK and a master key provider, it is an ideal point for customization and extension, such as support for policy enforcement and caching. Algorithm Suite The AWS Encryption SDK supports several (p. 13) algorithm suites (p. 11), all of which use Advanced Encryption Standard (AES) as the primary algorithm, and combine it with other algorithm and values. The AWS Encryption SDK establishes a recommended algorithm suite as the default for all encryption operations. The default might change as standards and best practices improve. You can specify an alternate algorithm suite in requests to encrypt data or when creating a cryptographic materials manager (CMM) (p. 7), but unless an alternate is required for your situation, it is best to use the default. The current default is AES-GCM with an HMAC-based extract-and-expand key derivation 7 AWS Encryption SDK Developer Guide Encryption Context function (HKDF), Elliptic Curve Digital Signature Algorithm (ECDSA) signing, and a 256-bit encryption key. If you specify an algorithm suite, we recommend an algorithm suite that uses a key derivation function and a message signing algorithm. Algorithm suites that have neither feature are supported only for backward compatibility. Encryption Context To improve the security of your cryptographic operations, use an encryption context in all requests to encrypt data. The encryption context is optional, but recommended. An encryption context is a set of key–value pairs that contain arbitrary nonsecret data. The encryption context can contain any data you choose, but it typically consists of data that is useful in logging and tracking, such as data about the file type, purpose, or ownership. In requests to encrypt data, you can include an encryption context along with the plaintext data and a master key provider. The Encryption SDK cryptographically binds the encryption context to the encrypted data so that the same encryption context is required to decrypt the data. The Encryption SDK also includes the encryption context in the encrypted message (p. 8) that it returns, along with the encrypted data and data keys. The encryption context in the encrypted message always includes the encryption context that you specified in the encryption request, along with elements that the operation might add, such as a public signing key. To decrypt the data, you pass in the encrypted message. Because the Encryption SDK can extract the encryption context from the message, you do not need to pass it in separately. After decrypting the data, the Encryption SDK returns a result that includes that encryption context along with the plaintext data. The functions in your application that decrypt data should always verify that the encryption context in the decrypt result includes the values that you expect before it returns the plaintext data. When choosing an encryption context, remember that it is not a secret. The encryption context is displayed in plaintext in the header of the encrypted message (p. 8) that the SDK returns. If you are using AWS Key Management Service, the encryption context also might appear in plaintext in audit records and logs, such as AWS CloudTrail. Encrypted Message Encrypt operations in the AWS Encryption SDK return an encrypted message and decrypt operations take an encrypted message as input. An encrypted message, a formatted data structure (p. 56) that includes the encrypted data along with encrypted copies of the data keys, the algorithm ID, and, optionally, an encryption context and a message signature. Combining the encrypted data and its encrypted data keys streamlines the decryption operation and frees you from having to store and manage encrypted data keys independently of the data that they encrypt. For technical information about the encrypted message, see Encrypted Message Format (p. 56). 8 AWS Encryption SDK Developer Guide Getting Started with the AWS Encryption SDK To use the AWS Encryption SDK, you need a master key provider (p. 7). If you don't have one, we recommend using AWS Key Management Service (AWS KMS). Many of the code samples in the Encryption SDK require an AWS KMS customer master key (CMK). To interact with AWS KMS, you need to use the AWS SDK for your preferred programming language, such as the AWS SDK for Java or the AWS SDK for Python (Boto). The Encryption SDK client library works with the AWS SDKs to support master keys stored in AWS KMS. To prepare to use the AWS Encryption SDK with AWS KMS 1. Create an AWS account. To learn how, see How do I create and activate a new Amazon Web Services account? in the AWS Knowledge Center. 2. Create a customer master key (CMK) in AWS KMS. To learn how, see Creating Keys in the AWS Key Management Service Developer Guide. Tip To use the CMK programmatically, you will need the ID or Amazon Resource Name (ARN) of the CMK. For help finding the ID or ARN of a CMK, see Viewing Keys in the AWS Key Management Service Developer Guide. 3. Create an IAM user with an access key. To learn how, see Creating IAM Users in the IAM User Guide. When you create the user, for Access type, choose Programmatic access. After you create the user, choose Download.csv to save the AWS access key that represents your user credentials. Store the file in a secure location. We recommend that you use AWS Identity and Access Management (IAM) access keys instead of AWS (root) account access keys. IAM lets you securely control access to AWS services and resources in your AWS account. For detailed best practice guidance, see Best Practices for Managing AWS Access Keys The Download.csv file contains an AWS access key ID and a secret access key that represents the AWS credentials of the user that you created. When you write code without using an AWS SDK, you use your access key to sign your requests to AWS. The signature assures AWS that the request came from you unchanged. However, when you use an AWS SDK, such as the AWS SDK for Java, the SDK signs all requests to AWS for you. 4. Set your AWS credentials using the instructions for Java or Python and the AWS access key in the Download.csv file that you downloaded in Step 3. 9 AWS Encryption SDK Developer Guide 5. This procedure allows AWS SDKs to sign requests to AWS for you. Code samples in the Encryption SDK that interact with AWS KMS assume that you have completed this step. Download and install the AWS Encryption SDK. To learn how, see the installation instructions for the programming language (p. 13) that you want to use. 10 AWS Encryption SDK Developer Guide Recommended: AES-GCM with Key Derivation and Signing Supported Algorithm Suites in the AWS Encryption SDK An algorithm suite is a collection of cryptographic algorithms and related values. Cryptographic systems use the algorithm implemenation to generate the ciphertext message. The AWS Encryption SDK algorithm suite uses the Advanced Encryption Standard (AES) algorithm in Galois/Counter Mode (GCM), known as AES-GCM, to encrypt raw data. The SDK supports 256-bit, 192bit, and 128-bit encryption keys. The length of the initialization vector (IV) is always 12 bytes; the length of the authentication tag is always 16 bytes. The SDK implements AES-GCM in one of three ways. By default, the SDK uses AES-GCM with an HMACbased extract-and-expand key derivation function (HKDF), signing, and a 256-bit encryption key. Recommended: AES-GCM with Key Derivation and Signing In the recommended algorithm suite, the SDK uses the data encryption key as an input to the HMACbased extract-and-expand key derivation function (HKDF) to derive the AES-GCM encryption key. The SDK also adds an Elliptic Curve Digital Signature Algorithm (ECDSA) signature. By default, the SDK uses this algorithm suite with a 256-bit encryption key. The HKDF helps you avoid accidental reuse of a data encryption key. This algorithm suite uses ECDSA and a message signing algorithm (SHA-384 or SHA-256). ECDSA is used by default, even when it is not specified by the policy for the underlying master key. Message signing verifies the identity of the message sender and adds message authenticity to the envelope encrypted data. It is particularly useful when the authorization policy for a master key allows one set of users to encrypt data and a different set of users to decrypt data. The following table lists the variations of the recommended algorithm suites. 11 AWS Encryption SDK Developer Guide Other Supported Algorithm Suites AWS Encryption SDK Algorithm Suites Algorithm Name Data Encryption Key Length (in bits) Algorithm Mode Key Derivation Algorithm Signature Algorithm AES 256 GCM HKDF with SHA-384 ECDSA with P-384 and SHA-384 AES 192 GCM HKDF with SHA-384 ECDSA with P-384 and SHA-384 AES 128 GCM HKDF with SHA-256 ECDSA with P-256 and SHA-256 Other Supported Algorithm Suites The AWS Encryption SDK supports the alternate algorithm suites for backward compatibility, although we do not recommend them. If you cannot use an algorithm suite with HKDF and signing, we recommend an algorithm suite with HKDF over one that lacks both elements. AES-GCM with Key Derivation Only This algorithm suite uses a key derivation function, but lacks the ECDSA signature that provides authenticity and nonrepudiation. Use this suite when the users who encrypt data and those who decrypt it are equally trusted. AES-GCM without Key Derivation or Signing This algorithm suite uses the data encryption key as the AES-GCM encryption key, instead of using a key derivation function to derive a unique key. We discourage using this suite to generate ciphertext, but the SDK supports it for compatibility reasons. For more information about how these suites are represented and used in the library, see the section called “Algorithms Reference” (p. 70). 12 AWS Encryption SDK Developer Guide Java AWS Encryption SDK Programming Languages The AWS Encryption SDK is available for the following programming languages. For more information, see the corresponding topic. Topics • AWS Encryption SDK for Java (p. 13) • AWS Encryption SDK for Python (p. 21) AWS Encryption SDK for Java This topic explains how to install and use the AWS Encryption SDK for Java. For details about programming with the SDK, see the aws-encryption-sdk-java repository on GitHub the Javadoc for the AWS Encryption SDK. Topics • Prerequisites (p. 13) • Installation (p. 14) • AWS Encryption SDK for Java Example Code (p. 14) Prerequisites Before you install the AWS Encryption SDK for Java, be sure you have the following prerequisites. A Java development environment You will need Java 8 or later. On the Oracle website, go to Java SE Downloads, and then download and install the Java SE Development Kit (JDK). 13 AWS Encryption SDK Developer Guide Installation If you use the Oracle JDK, you must also download and install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. Bouncy Castle Bouncy Castle provides a cryptography API for Java. If you don't have Bouncy Castle, go to Bouncy Castle latest releases to download the provider file that corresponds to your JDK. If you use Apache Maven, Bouncy Castle is available with the following dependency definition.AWS SDK for Java (Optional) Although you don't need the AWS SDK for Java to use the AWS Encryption SDK for Java, you do need it to use AWS Key Management Service (AWS KMS) as a master key provider, and to use some of the example Java code (p. 14) in this guide. For more information about installing and configuring the AWS SDK for Java, see AWS SDK for Java. Installation You can install the AWS Encryption SDK for Java in the following ways. Manually To install the AWS Encryption SDK for Java, clone or download the aws-encryption-sdk-java GitHub repository. Using Apache Maven The AWS Encryption SDK for Java is available through Apache Maven with the following dependency definition. org.bouncycastle bcprov-ext-jdk15on 1.58 After you install the SDK, get started by looking at the example Java code (p. 14) in this guide and the Javadoc on GitHub. AWS Encryption SDK for Java Example Code The following examples show you how to use the AWS Encryption SDK for Java to encrypt and decrypt data. Topics • Encrypting and Decrypting Strings (p. 15) • Encrypting and Decrypting Byte Streams (p. 16) • Encrypting and Decrypting Byte Streams with Multiple Master Key Providers (p. 18) 14 AWS Encryption SDK Developer Guide Example Code Encrypting and Decrypting Strings The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt strings. This example uses an AWS Key Management Service (AWS KMS) customer master key (CMK) as the master key. For help creating a key, see Creating Keys in the AWS Key Management Service Developer Guide. To find the Amazon Resource name (ARN) of an existing CMK, go to the Encryption keys section of the AWS Management Console, select the region, and then click the CMK alias. You can also use the AWS KMS ListKeys operation. For details, see Viewing Keys in the AWS Key Management Service Developer Guide. /* * 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 java.util.Collections; import java.util.Map; import import import import com.amazonaws.encryptionsdk.AwsCrypto; com.amazonaws.encryptionsdk.CryptoResult; com.amazonaws.encryptionsdk.kms.KmsMasterKey; com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; /** * com.amazonaws aws-encryption-sdk-java 1.3.1 * Encrypts and then decrypts a string under a KMS key * *
* Arguments: *
*
*/ public class StringExample { private static String keyArn; private static String data; public static void main(final String[] args) { keyArn = args[0]; data = args[1]; // Instantiate the SDK final AwsCrypto crypto = new AwsCrypto(); 15 AWS Encryption SDK Developer Guide Example Code // Set up the KmsMasterKeyProvider backed by the default credentials final KmsMasterKeyProvider prov = new KmsMasterKeyProvider(keyArn); // Encrypt the data // // 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-Integrityof-Your-Encrypted-Data-by-Using-AWS-Key-Management final Map- 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 *
- String to encrypt *
context = Collections.singletonMap("Example", "String"); final String ciphertext = crypto.encryptString(prov, data, context).getResult(); System.out.println("Ciphertext: " + ciphertext); // Decrypt the data final CryptoResult decryptResult = crypto.decryptString(prov, ciphertext); // Before returning 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!"); } // Also, verify that the encryption context in the result contains the // encryption context supplied to the encryptString method. Because the // SDK can add values to the encryption context, don't require that // the entire context matches. for (final Map.Entry e : context.entrySet()) { if (!e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey()))) { } } } } throw new IllegalStateException("Wrong Encryption Context!"); // Now we can return the plaintext data System.out.println("Decrypted: " + decryptResult.getResult()); Encrypting and Decrypting Byte Streams The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt byte streams. This example does not use AWS. It uses the Java Cryptography Extension (JCE) to protect the master key. /* * 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. 16 AWS Encryption SDK Developer Guide Example Code */ package com.amazonaws.crypto.examples; import import import import import import java.io.FileInputStream; java.io.FileOutputStream; java.io.IOException; java.security.SecureRandom; java.util.Collections; java.util.Map; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import import import import import com.amazonaws.encryptionsdk.AwsCrypto; com.amazonaws.encryptionsdk.CryptoInputStream; com.amazonaws.encryptionsdk.MasterKey; com.amazonaws.encryptionsdk.jce.JceMasterKey; com.amazonaws.util.IOUtils; /** * * Encrypts and then decrypts a file under a random key. * *
* Arguments: *
*
* *- 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(); 17 AWS Encryption SDK Developer Guide Example Code 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"); } Encrypting and Decrypting Byte Streams with Multiple Master Key Providers The following example shows you how to use the AWS Encryption SDK with more than one master key provider. Using more than one master key provider creates redundancy if one master key provider is unavailable for decryption. This example uses a CMK in AWS KMS and an RSA key pair as the master keys. /* * 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 import import import import import java.io.FileInputStream; java.io.FileOutputStream; java.security.GeneralSecurityException; java.security.KeyPair; java.security.KeyPairGenerator; java.security.PrivateKey; 18 AWS Encryption SDK Developer Guide Example Code import java.security.PublicKey; import import import import import import import com.amazonaws.encryptionsdk.AwsCrypto; com.amazonaws.encryptionsdk.CryptoOutputStream; com.amazonaws.encryptionsdk.MasterKeyProvider; com.amazonaws.encryptionsdk.jce.JceMasterKey; com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; com.amazonaws.encryptionsdk.multi.MultipleProviderFactory; com.amazonaws.util.IOUtils; /** * * Encrypts a file using both KMS and an asymmetric key pair. * *
* Arguments: *
*
* * 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 19 AWS Encryption SDK Developer Guide Example Code // 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); always // 5. Encrypt the file // To simplify the code, we omit the encryption context. Production code should // 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); always // 5. Decrypt the file // To simplify the code, we omit the encryption context. Production code should // 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(); } 20 AWS Encryption SDK Developer Guide Python 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 // This method call uses the escrowed private key, not null final JceMasterKey escrowPriv = JceMasterKey.getInstance(publicEscrowKey, privateEscrowKey, "Escrow", "Escrow", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); always // 3. Decrypt the file // To simplify the code, we omit the encryption context. Production code should // 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(); } } AWS Encryption SDK for Python This topic explains how to install and use the AWS Encryption SDK for Python. For details about programming with the SDK, see the aws-encryption-sdk-python repository on GitHub and the Python documentation for the AWS Encryption SDK for Python. Topics • Prerequisites (p. 21) • Installation (p. 22) • AWS Encryption SDK for Python Example Code (p. 22) Prerequisites Before you install the AWS Encryption SDK for Python, be sure you have the following prerequisites. A supported version of Python To use this SDK, you need Python 2.7, or Python 3.3 or later. To download Python, see Python downloads. 21 AWS Encryption SDK Developer Guide Installation The pip installation tool for Python If you have Python 2.7.9 or later, or Python 3.4 or later, you already have pip, though you might want to upgrade it. For more information about upgrading or installing pip, see Installation in the pip documentation. Installation Use pip to install the AWS Encryption SDK for Python, as shown in the following examples. To install the latest version pip install aws-encryption-sdk To install a specific version The following example installs version 1.2.0. pip install aws-encryption-sdk=1.2.0 When you use pip to install the SDK on Linux, pip builds the cryptography library, one of the SDK's dependencies. If your Linux environment doesn't have the tools needed to build the cryptography library, you must install them. For more information, see Building cryptography on Linux. For the latest development version of this SDK, go to the aws-encryption-sdk-python GitHub repository. After you install the SDK, get started by looking at the example Python code (p. 22) in this guide. AWS Encryption SDK for Python Example Code The following examples show you how to use the AWS Encryption SDK for Python to encrypt and decrypt data. Topics • Encrypting and Decrypting Strings (p. 22) • Encrypting and Decrypting Byte Streams (p. 23) • Encrypting and Decrypting Byte Streams with Multiple Master Key Providers (p. 25) Encrypting and Decrypting Strings The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt strings. This example uses a customer master key (CMK) in AWS Key Management Service (AWS KMS) as the master key. """ 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 https://aws.amazon.com/apache-2-0/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 22 AWS Encryption SDK Developer Guide Example Code 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. """ from __future__ import print_function import aws_encryption_sdk def cycle_string(key_arn, source_plaintext, botocore_session=None): """Encrypts and then decrypts a string using a KMS customer master key (CMK) :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html) :param bytes source_plaintext: Data to encrypt :param botocore_session: Existing Botocore session instance :type botocore_session: botocore.session.Session """ # Create a KMS master key provider kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) # Encrypt the plaintext source data ciphertext, encryptor_header = aws_encryption_sdk.encrypt( source=source_plaintext, key_provider=master_key_provider ) print('Ciphertext: ', ciphertext) # Decrypt the ciphertext cycled_plaintext, decrypted_header = aws_encryption_sdk.decrypt( source=ciphertext, key_provider=master_key_provider ) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext assert cycled_plaintext == source_plaintext # Verify that the encryption context used in the decrypt operation includes all key pairs from # the encrypt operation. (The SDK can add pairs, so don't require an exact match.) # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in decrypted_header.encryption_context.items() for pair in encryptor_header.encryption_context.items() ) print('Decrypted: ', cycled_plaintext) Encrypting and Decrypting Byte Streams The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt byte streams. This example doesn't use AWS. It uses a static, ephemeral master key provider. """ 23 AWS Encryption SDK Developer Guide Example Code 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 https://aws.amazon.com/apache-2-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. """ import filecmp import os import aws_encryption_sdk from aws_encryption_sdk.internal.crypto import WrappingKey from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider from aws_encryption_sdk.identifiers import WrappingAlgorithm, EncryptionKeyType class StaticRandomMasterKeyProvider(RawMasterKeyProvider): """Randomly and consistently generates 256-bit keys for each unique key ID.""" provider_id = 'static-random' def __init__(self, **kwargs): self._static_keys = {} def _get_raw_key(self, key_id): """Returns a static, randomly-generated symmetric key for the specified key ID. :param str key_id: Key ID :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: static_key = self._static_keys[key_id] except KeyError: static_key = os.urandom(32) self._static_keys[key_id] = static_key return WrappingKey( wrapping_algorithm=WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING, wrapping_key=static_key, wrapping_key_type=EncryptionKeyType.SYMMETRIC ) def cycle_file(source_plaintext_filename): """Encrypts and then decrypts a file under a custom static master key provider. :param str source_plaintext_filename: Filename of file to encrypt """ # Create a static random master key provider key_id = os.urandom(8) master_key_provider = StaticRandomMasterKeyProvider() master_key_provider.add_master_key(key_id) ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_plaintext_filename = source_plaintext_filename + '.decrypted' # Encrypt the plaintext source data 24 AWS Encryption SDK Developer Guide Example Code with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( mode='e', source=plaintext, key_provider=master_key_provider ) as encryptor: for chunk in encryptor: ciphertext.write(chunk) # Decrypt the ciphertext with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( mode='d', source=ciphertext, key_provider=master_key_provider ) as decryptor: for chunk in decryptor: plaintext.write(chunk) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext assert filecmp.cmp(source_plaintext_filename, cycled_plaintext_filename) # Verify that the encryption context used in the decrypt operation includes all key pairs from # the encrypt operation # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) return ciphertext_filename, cycled_plaintext_filename Encrypting and Decrypting Byte Streams with Multiple Master Key Providers The following example shows you how to use the AWS Encryption SDK with more than one master key provider. Using more than one master key provider creates redundancy if one master key provider is unavailable for decryption. This example uses a CMK in AWS KMS and an RSA key pair as the master keys. """ 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 https://aws.amazon.com/apache-2-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. """ import filecmp 25 AWS Encryption SDK Developer Guide Example Code import os import aws_encryption_sdk from aws_encryption_sdk.internal.crypto import WrappingKey from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider from aws_encryption_sdk.identifiers import WrappingAlgorithm, EncryptionKeyType from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa class StaticRandomMasterKeyProvider(RawMasterKeyProvider): provider_id = 'static-random' def __init__(self, **kwargs): self._static_keys = {} def _get_raw_key(self, key_id): """Returns a static, randomly generated, RSA key for the specified key ID. :param str key_id: User-defined ID for the static key :returns: Wrapping key that contains the specified static key :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` """ try: static_key = self._static_keys[key_id] except KeyError: private_key = rsa.generate_private_key( public_exponent=65537, key_size=4096, backend=default_backend() ) static_key = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) self._static_keys[key_id] = static_key return WrappingKey( wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA1_MGF1, wrapping_key=static_key, wrapping_key_type=EncryptionKeyType.PRIVATE ) def cycle_file(key_arn, source_plaintext_filename, botocore_session=None): """Encrypts and then decrypts a file using a KMS master key provider and a custom static master key provider. Both master key providers are used to encrypt the plaintext file, so either one alone can decrypt it. :param str key_arn: Amazon Resource Name (ARN) of the KMS Customer Master Key (CMK) (http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html) :param str source_plaintext_filename: Filename of file to encrypt :param botocore_session: existing botocore session instance :type botocore_session: botocore.session.Session """ # "Cycled" means encrypted and then decrypted ciphertext_filename = source_plaintext_filename + '.encrypted' cycled_kms_plaintext_filename = source_plaintext_filename + '.kms.decrypted' cycled_static_plaintext_filename = source_plaintext_filename + '.static.decrypted' # Create a KMS master key provider kms_kwargs = dict(key_ids=[key_arn]) 26 AWS Encryption SDK Developer Guide Example Code if botocore_session is not None: kms_kwargs['botocore_session'] = botocore_session kms_master_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) # Create a static master key provider and add a master key to it static_key_id = os.urandom(8) static_master_key_provider = StaticRandomMasterKeyProvider() static_master_key_provider.add_master_key(static_key_id) # Create a master key provider that includes the KMS and static master key providers kms_master_key_provider.add_master_key_provider(static_master_key_provider) # Encrypt plaintext with both KMS and static master keys with open(source_plaintext_filename, 'rb') as plaintext, open(ciphertext_filename, 'wb') as ciphertext: with aws_encryption_sdk.stream( source=plaintext, mode='e', key_provider=kms_master_key_provider ) as encryptor: for chunk in encryptor: ciphertext.write(chunk) # Decrypt the ciphertext with only the KMS master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_kms_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, mode='d', key_provider=aws_encryption_sdk.KMSMasterKeyProvider(**kms_kwargs) ) as kms_decryptor: for chunk in kms_decryptor: plaintext.write(chunk) # Decrypt the ciphertext with only the static master key with open(ciphertext_filename, 'rb') as ciphertext, open(cycled_static_plaintext_filename, 'wb') as plaintext: with aws_encryption_sdk.stream( source=ciphertext, mode='d', key_provider=static_master_key_provider ) as static_decryptor: for chunk in static_decryptor: plaintext.write(chunk) # Verify that the "cycled" (encrypted, then decrypted) plaintext is identical to the source # plaintext assert filecmp.cmp(source_plaintext_filename, cycled_kms_plaintext_filename) assert filecmp.cmp(source_plaintext_filename, cycled_static_plaintext_filename) # Verify that the encryption context in the decrypt operation includes all key pairs from the # encrypt operation. # # In production, always use a meaningful encryption context. In this sample, we omit the # encryption context (no key pairs). assert all( pair in kms_decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) assert all( pair in static_decryptor.header.encryption_context.items() for pair in encryptor.header.encryption_context.items() ) 27 AWS Encryption SDK Developer Guide Example Code return ciphertext_filename, cycled_kms_plaintext_filename, cycled_static_plaintext_filename 28 AWS Encryption SDK Developer Guide Data Key Caching Data key caching stores data keys (p. 6) and related cryptographic material (p. 39) in a cache. When you encrypt or decrypt data, the AWS Encryption SDK looks for a matching data key in the cache. If it finds a match, it uses the cached data key rather than generating a new one. Data key caching can improve performance, reduce cost, and help you stay within service limits as your application scales. Your application can benefit from data key caching if: • It can reuse data keys. • It generates numerous data keys. • Your cryptographic operations are unacceptably slow, expensive, limited, or resource-intensive. Caching can reduce your use of cryptographic services, such as AWS Key Management Service (AWS KMS). If you are hitting your AWS KMS requests-per-second limit, caching can help. Your application can use cached keys to service some of your data key requests instead of calling AWS KMS. (You can also create a case in the AWS Support Center to raise the limit for your account.) The AWS Encryption SDK helps you to create and manage your data key cache. It provides a LocalCryptoMaterialsCache (p. 38) and a caching cryptographic materials manager (p. 39) that interacts with the cache and enforces security thresholds (p. 34) that you set. Working together, these components help you to benefit from the efficiency of reusing data keys while maintaining the security of your system. Data key caching is an optional feature of the AWS Encryption SDK that you should use cautiously. By default, the Encryption SDK generates a new data key for every encryption operation. This technique supports cryptographic best practices, which discourage excessive reuse of data keys. In general, use data key caching only when it is required to meet your performance goals. Then, use the data key caching security thresholds (p. 34) to ensure that you use the minimum amount of caching required to meet your cost and performance goals. For a detailed discussion of these security tradeoffs, see AWS Encryption SDK: How to Decide if Data Key Caching is Right for Your Application in the AWS Security Blog. Topics • How to Implement Data Key Caching (p. 30) • Setting Cache Security Thresholds (p. 34) • Data Key Caching Details (p. 36) • Data Key Caching Example (p. 40) 29 AWS Encryption SDK Developer Guide How to Implement Data Key Caching How to Implement Data Key Caching This topic shows you how to implement data key caching in your application. It takes you through the process step by step. Then, it combines the steps in a simple example that uses data key caching in an operation to encrypt a string. Topics • Implement Data Key Caching: Step-by-Step (p. 30) • Data Key Caching Example: Encrypt a String (p. 32) Implement Data Key Caching: Step-by-Step These step-by-step instructions show you how to create the components that you need to implement data key caching. • Create a data key cache (p. 38), such as a LocalCryptoMaterialsCache. Java //Cache capacity (maximum number of entries) is required int MAX_CACHE_SIZE = 10; CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(MAX_CACHE_SIZE); Python # Cache capacity (maximum number of entries) is required MAX_CACHE_SIZE = 10 cache = LocalCryptoMaterialsCache(MAX_CACHE_SIZE) • Create a master key provider (p. 7). This example uses an AWS Key Management Service (AWS KMS) master key provider. Java //Create a KMS master key provider // The input is the Amazon Resource Name (ARN) // of a KMS customer master key (CMK) MasterKeyProvider- 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 *
- Name of file containing plaintext data to encrypt *
keyProvider = new KmsMasterKeyProvider(kmsCmkArn); Python # Create a KMS master key provider # The input is the Amazon Resource Name (ARN) # of a KMS customer master key (CMK) key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[kms_cmk_arn]) 30 AWS Encryption SDK Developer Guide Implement Data Key Caching: Step-by-Step • Create a caching cryptographic materials manager (p. 39) (caching CMM). Associate your caching CMM with your cache and master key provider. Then, set cache security thresholds (p. 34) on the caching CMM. Java /* * Security thresholds * Max entry age is required. * Max messages (and max bytes) per entry are optional */ int MAX_ENTRY_AGE_SECONDS = 60; int MAX_ENTRY_MSGS = 10; //Create a caching CMM CryptoMaterialsManager cachingCmm = CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider) .withCache(cache) .withMaxAge(MAX_ENTRY_AGE_SECONDS, TimeUnit.SECONDS) .withMessageUseLimit(MAX_ENTRY_MSGS) .build(); Python # Security thresholds # Max entry age is required. # Max messages (and max bytes) per entry are optional # MAX_ENTRY_AGE_SECONDS = 60.0 MAX_ENTRY_MESSAGES = 10 # Create a caching CMM caching_cmm = CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=MAX_ENTRY_AGE_SECONDS, max_messages_encrypted=MAX_ENTRY_MESSAGES ) That's all you need to do. Then, let the AWS Encryption SDK manage the cache for you, or add your own cache management logic. When you want to use data key caching in a call to encrypt or decrypt data, specify your caching CMM instead of a master key provider or other CMM. Note If you are encrypting data streams, or any data of unknown size, be sure to specify the data size in the request. The Encryption SDK does not use data key caching when encrypting data of unknown size. Java // When the call to encryptData specifies a caching CMM, // the encryption operation uses the data key cache // final AwsCrypto encryptionSdk = new AwsCrypto(); 31 AWS Encryption SDK Developer Guide Data Key Caching Example: Encrypt a String byte[] message = new AwsCrypto().encryptData(cachingCmm, plaintext_source).getResult(); Python # When the call to encrypt specifies a caching CMM, # the encryption operation uses the data key cache # encrypted_message, header = aws_encryption_sdk.encrypt( source=plaintext_source, materials_manager=caching_cmm ) Data Key Caching Example: Encrypt a String This simple code example uses data key caching when encrypting a string. It combines the code from the step-by-step procedure (p. 30) into test code that you can run. The example creates a LocalCryptoMaterialsCache (p. 38) and a master key provider (p. 7) for an AWS KMS customer master key (CMK). Then, it uses the cache and master key provider to create a caching CMM with appropriate security thresholds (p. 34). The encryption request specifies the caching CMM, the plaintext data to encrypt, and an encryption context (p. 40). To run the example, you need to supply the Amazon Resource Name (ARN) of a KMS CMK. Be sure that you have permission to use the CMK to generate a data key. For more detailed, real-world examples of creating and using a data key cache, see Data Key Caching Example in Java (p. 42) and Data Key Caching Example in Python (p. 46). Java /* * 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. */ import import import import java.nio.charset.StandardCharsets; java.util.Collections; java.util.Map; java.util.concurrent.TimeUnit; import javax.xml.bind.DatatypeConverter; import import import import com.amazonaws.encryptionsdk.AwsCrypto; com.amazonaws.encryptionsdk.CryptoMaterialsManager; com.amazonaws.encryptionsdk.MasterKeyProvider; com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager; 32 AWS Encryption SDK Developer Guide Data Key Caching Example: Encrypt a String import import import import com.amazonaws.encryptionsdk.caching.CryptoMaterialsCache; com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache; com.amazonaws.encryptionsdk.kms.KmsMasterKey; com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; /** * * Encrypts a string using an AWS KMS customer master key (CMK) and data key caching * *
* Arguments: *
*
*/ public class SimpleDataKeyCachingExample { /* * Security thresholds * Max entry age is required. * Max messages (and max bytes) per data key are optional */ private static final int MAX_ENTRY_MSGS = 100; public static byte[] encryptWithCaching(String kmsCmkArn, int maxEntryAge, int cacheCapacity) { // Plaintext data to be encrypted byte[] myData = "My plaintext data".getBytes(StandardCharsets.UTF_8); // Encryption context final Map- KMS CMK ARN: To find the Amazon Resource Name of your AWS KMS customer master key (CMK), * see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/ viewing-keys.html *
- Max entry age: Maximum time (in seconds) that a cached entry can be used *
- Cache capacity: Maximum number of entries in the cache *
encryptionContext = Collections.singletonMap("purpose", "test"); // Create a master key provider MasterKeyProvider keyProvider = new KmsMasterKeyProvider(kmsCmkArn); // Create a cache CryptoMaterialsCache cache = new LocalCryptoMaterialsCache(cacheCapacity); // Create a caching CMM CryptoMaterialsManager cachingCmm = CachingCryptoMaterialsManager.newBuilder().withMasterKeyProvider(keyProvider) .withCache(cache) .withMaxAge(maxEntryAge, TimeUnit.SECONDS) .withMessageUseLimit(MAX_ENTRY_MSGS) .build(); // When the call to encryptData specifies a caching CMM, // the encryption operation uses the data key cache // final AwsCrypto encryptionSdk = new AwsCrypto(); return encryptionSdk.encryptData(cachingCmm, myData, encryptionContext).getResult(); } Python # Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. 33 AWS Encryption SDK Developer Guide Setting Cache Security Thresholds # # 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. """Example of basic configuration and use of data key caching.""" import aws_encryption_sdk def encrypt_with_caching(kms_cmk_arn, max_age_in_cache, cache_capacity): """Encrypts a string using an AWS KMS customer master key (CMK) and data key caching. :param str kms_cmk_arn: Amazon Resource Name (ARN) of the KMS customer master key :param float max_age_in_cache: Maximum time in seconds that a cached entry can be used :param int cache_capacity: Maximum number of entries in the cache """ # Data to be encrypted my_data = 'My plaintext data' # Security thresholds # Max messages (and max bytes) per data key are optional MAX_ENTRY_MESSAGES = 100 # Create an encryption context. encryption_context = {'purpose': 'test'} # Create a master key provider for the KMS master key key_provider = aws_encryption_sdk.KMSMasterKeyProvider(key_ids=[kms_cmk_arn]) # Create a cache cache = aws_encryption_sdk.LocalCryptoMaterialsCache(cache_capacity) # Create a caching CMM caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager( master_key_provider=key_provider, cache=cache, max_age=max_age_in_cache, max_messages_encrypted=MAX_ENTRY_MESSAGES ) # When the encrypt request specifies a caching CMM, # the encryption operation uses the data key cache encrypted_message, _header = aws_encryption_sdk.encrypt( source=my_data, materials_manager=caching_cmm, encryption_context=encryption_context ) return encrypted_message Setting Cache Security Thresholds When you implement data key caching, you need to configure the security thresholds that the caching CMM (p. 39) enforces. 34 AWS Encryption SDK Developer Guide Setting Cache Security Thresholds The security thresholds help you to limit how long each cached data key is used and how much data is protected under each data key. The caching CMM returns cached data keys only when the cache entry conforms to all of the security thresholds. If the cache entry exceeds any threshold, the entry is not used for the current operation and it is evicted from the cache. As a rule, use the minimum amount of caching that is required to meet your cost and performance goals. The Encryption SDK only caches data keys that are encrypted by using a key derivation function. Also, it establishes upper limits for the threshold values. These restrictions ensure that data keys are not reused beyond their cryptographic limits. However, because your plaintext data keys are cached (in memory, by default), try to minimize the time that the keys are saved . Also, try to limit the data that might be exposed if a key is compromised. For examples of setting cache security thresholds, see AWS Encryption SDK: How to Decide if Data Key Caching is Right for Your Application in the AWS Security Blog. Note The caching CMM enforces all of the following thresholds. If you do not specify an optional value, the caching CMM uses the default value. To disable data key caching temporarily, do not set the cache capacity (p. 38) or security thresholds to 0. Instead, use the null cryptographic materials cache (NullCryptoMaterialsCache) that the Encryption SDK provides. The NullCryptoMaterialsCache returns a miss for every get request and does not respond to put requests. For more information, see the SDK for your programming language (p. 13). Maximum age (required) Determines how long a cached entry can be used, beginning when it was added. This value is required. Enter a value greater than 0. There is no maximum value. The LocalCryptoMaterialsCache tries to evict cache entries as soon as possible after they reach the maximum age value. Other conforming caches might perform differently. Use the shortest interval that still allows your application to benefit from the cache. You can use the maximum age threshold like a key rotation policy. Use it to limit reuse of data keys, minimize exposure of cryptographic materials, and evict data keys whose policies might have changed while they were cached. Maximum messages encrypted (optional) Specifies the maximum number of messages that a cached data key can encrypt. This value is optional. Enter a value between 1 and 2^32 messages. The default value is 2^32 messages. Set the number of messages protected by each cached key to be large enough to get value from reuse, but small enough to limit the number of messages that might be exposed if a key is compromised. Maximum bytes encrypted (optional) Specifies the maximum number of bytes that a cached data key can encrypt. This value is optional. Enter a value between 0 and 2^63 - 1. The default value is 2^63 - 1. A value of 0 lets you encrypt empty message strings. The first use of each data key (before caching) is exempt from this threshold. Also, to enforce this threshold, requests to encrypt data of unknown size, such as streamed data with no length specifier, do not use the data key cache. The bytes in the current request are included when evaluating this threshold. If the bytes processed, plus current bytes, exceed the threshold, the cached data key is evicted from the cache, even though it might have been used on a smaller request. 35 AWS Encryption SDK Developer Guide Data Key Caching Details Data Key Caching Details Most applications can use the default implementation of data key caching without writing custom code. This section describes the default implementation and some details about options. Topics • How Data Key Caching Works (p. 36) • Creating a Cryptographic Materials Cache (p. 38) • Creating a Caching Cryptographic Materials Manager (p. 39) • What Is in a Data Key Cache Entry? (p. 39) • Encryption Context: How to Select Cache Entries (p. 40) How Data Key Caching Works When you use data key caching in a request to encrypt or decrypt data, the Encryption SDK first searches the cache for a data key that matches the request. If it finds a valid match, it uses the cached data key to encrypt the data. Otherwise, it generates a new data key, just as it would without the cache. In addition to a cache, data key caching uses a caching cryptographic materials manager (p. 39) (caching CMM). The caching CMM is a specialized cryptographic materials manager (CMM) (p. 7) that interacts with a cache (p. 38) and an underlying CMM (p. 7) or master key provider (p. 7). The caching CMM caches the data keys that its underlying CMM (or master key provider) returns. The caching CMM also enforces cache security thresholds that you set. To prevent the wrong data key from being selected from the cache, each caching CMM requires that several properties of each cached data key match the materials request, as follows: • For encryption material requests, the cached entry and the request must have the same algorithm suite (p. 7), encryption context (p. 40) (even when empty), and partition name (a string that identifies the caching CMM). • For decryption material requests, the cached entry and the request must have the same algorithm suite (p. 7), encryption context (p. 40) (even when empty), and partition name (a string that identifies the caching CMM). Note The Encryption SDK caches data keys only when the algorithm suite (p. 7) uses a key derivation function. Data key caching is not used for data of unknown size, such as streamed data. This allows the caching CMM to properly enforce the maximum bytes threshold (p. 34). To avoid this behavior, add the data length to the encryption request. The following workflows show how a request to encrypt data is processed with and without data key caching. They show how the caching components that you create, including the cache and the caching CMM, are used in the process. Encrypt Data without Caching To generate a data key without caching: 1. An application asks the AWS Encryption SDK to encrypt data. The request specifies a cryptographic materials manager (CMM) or master key provider. If you specify a master key provider, the Encryption SDK creates a default CMM that interacts with the master key provider you specified. 36 AWS Encryption SDK Developer Guide How Data Key Caching Works 2. The Encryption SDK asks the CMM for a data key to encrypt the data (get cryptographic materials). 3. The CMM asks its master key provider for master keys (p. 6) (or objects that represent master keys). Then, it uses the master keys to generate a new data key (p. 6). This might involve a call to a cryptographic service, such as AWS Key Management Service (AWS KMS). The CMM returns plaintext and encrypted copies of the data key to the Encryption SDK. 4. The Encryption SDK uses the plaintext data key to encrypt the data and it returns an encrypted message (p. 8) to the user. Encrypt Data with Caching To generate a data key with data key caching: 1. An application asks the AWS Encryption SDK to encrypt data. The request specifies a caching cryptographic materials manager (caching CMM) (p. 39) that is associated with a default cryptographic materials manager (CMM) or a master key provider. If you specify a master key provider, the SDK creates a default CMM for you. 2. The SDK asks the specified caching CMM for a data key to encrypt the data (get cryptographic materials). 3. The caching CMM requests a data key from the cache. a. If the cache finds a match, it updates the age and use values of the matched cache entry, and returns the cached data key to the caching CMM. If the cache entry conforms to its security thresholds (p. 34), the caching CMM returns it to the SDK. Otherwise, it tells the cache to evict the entry and proceeds as though there was no match. 37 AWS Encryption SDK Developer Guide Creating a Cryptographic Materials Cache b. If the cache cannot find a valid match, the caching CMM asks its underlying CMM to generate a new data key. The CMM gets master keys (or objects that represent master keys) from its master key provider and it uses them to generate a new data key. This might involve a call to a service, such as AWS Key Management Service. The CMM returns the plaintext and encrypted copies of the data key to the caching CMM. The caching CMM saves the new data key in the cache. 4. The caching CMM returns plaintext and encrypted copies of the data key to the Encryption SDK. 5. The Encryption SDK uses the data key to encrypt the data and it returns an encrypted message (p. 8) to the user. Creating a Cryptographic Materials Cache The AWS Encryption SDK defines the requirements for a cryptographic materials cache used in data key caching. It also provides LocalCryptoMaterialsCache, a configurable, in-memory, least recently used (LRU) cache, and a null cryptographic materials cache for testing. LocalCryptoMaterialsCache includes logic for basic cache management, including adding, evicting, and matching cached entries, and maintaining the cache. You don't need to write any custom cache management logic. You can use LocalCryptoMaterialsCache as is, customize it, or substitute any compatible cache. When you create a LocalCryptoMaterialsCache, you set its capacity, that is, the maximum number of entries that the cache can hold. This setting helps you to design an efficient cache with limited data key reuse. 38 AWS Encryption SDK Developer Guide Creating a Caching Cryptographic Materials Manager The Encryption SDK also provides a null cryptographic materials cache (NullCryptoMaterialsCache). The NullCryptoMaterialsCache returns a miss for all get operations and does not respond to put operations. You can use the NullCryptoMaterialsCache in testing or to temporarily disable caching in an application that includes caching code. In the Encryption SDK, each cryptographic materials cache is associated with a caching cryptographic materials manager (p. 39) (caching CMM). The caching CMM gets data keys from the cache, puts data keys in the cache, and enforces security thresholds (p. 34) that you set. When you create a caching CMM, you specify the cache that it uses and the underlying CMM or master key provider that generates the data keys that it caches. Creating a Caching Cryptographic Materials Manager To enable data key caching, you create a cache (p. 38) and a caching cryptographic materials manager (caching CMM). Then, in your requests to encrypt or decrypt data, you specify a caching CMM, instead of a standard cryptographic materials manager (CMM) (p. 7) or master key provider (p. 7) . There are two types of CMMs. Both get data keys (and related cryptographic material), but in different ways, as follows: • A CMM is associated with a master key provider. When the SDK asks the CMM for data keys (get encryption materials), the CMM gets master keys (or objects that represent master keys) from its master key provider. Then, it uses the master keys to generate, encrypt, or decrypt the data keys. • A caching CMM is associated with one cache, such as a LocalCryptoMaterialsCache (p. 38), and a CMM or master key provider. (If you specify a master key provider, the SDK creates a default CMM for the master key provider.) When the SDK asks the caching CMM for data keys, the caching CMM tries to get them from the cache. If it cannot find a valid, matching data key, the caching CMM asks its underlying CMM for the data keys. Then, it caches those data keys before returning them to the caller. The caching CMM also enforces security thresholds (p. 34) that you set for each cache entry. Because the security thresholds are set in and enforced by the caching CMM, you can use any compatible cache, even if the cache is not designed for sensitive material. For details about creating and managing CMMs and caching CMMs in your application, see the SDK for your programming language (p. 13). What Is in a Data Key Cache Entry? Data key caching stores data keys and related cryptographic materials in a cache. Each entry includes the elements listed below. You might find this information useful when you're deciding whether to use the data key caching feature, and when you're setting security thresholds on a caching cryptographic materials manager (caching CMM). Cached Entries for Encryption Requests The entries that are added to a data key cache as a result of a encryption operation include the following elements: • Plaintext data key • Encrypted data keys (one or more) • Encryption context (p. 40) • Message signing key (if one is used) 39 AWS Encryption SDK Developer Guide Encryption Context: How to Select Cache Entries • Algorithm suite (p. 7) • Metadata, including usage counters for enforcing security thresholds Cached Entries for Decryption Requests The entries that are added to a data key cache as a result of a decryption operation include the following elements: • Plaintext data key • Signature verification key (if one is used) • Metadata, including usage counters for enforcing security thresholds Encryption Context: How to Select Cache Entries You can specify an encryption context in any request to encrypt data. However, the encryption context plays a special role in data key caching. It lets you create subgroups of data keys in your cache, even when the data keys originate from the same caching CMM. An encryption context (p. 8) is a set of key-value pairs that contain arbitrary nonsecret data. During encryption, the encryption context is cryptographically bound to the encrypted data so that the same encryption context is required to decrypt the data. In the AWS Encryption SDK, the encryption context is stored in the encrypted message (p. 8) along with the encrypted data and data keys. When you use a data key cache, you can also use the encryption context to select particular cached data keys for your encryption operations. The encryption context is saved in the cache entry with the data key (it's part of the cache entry ID). Cached data keys are reused only when their encryption contexts match. If you want to reuse certain data keys for an encryption request, specify the same encryption context. If you want to avoid those data keys, specify a different encryption context. The encryption context is always optional, but recommended. If you don't specify an encryption context in your request, an empty encryption context is included in the cache entry identifier and matched to each request. Data Key Caching Example This example uses data key caching (p. 29) with a LocalCryptoMaterialsCache (p. 38) to speed up an application in which data generated by multiple devices is encrypted and stored in different regions. In this scenario, multiple data producers generate data, encrypt it, and write to a Kinesis stream in each region. AWS Lambda functions (consumers) decrypt the streams and write plaintext data to a DynamoDB table in the region. Data producers and consumers use the Encryption SDK and a KMS master key provider (p. 7). To reduce calls to KMS, each producer and consumer has their own LocalCryptoMaterialsCache. You can find the source code for these examples in Java (p. 42) and Python (p. 46). The sample also includes a AWS CloudFormation template that defines the resources for the samples. 40 AWS Encryption SDK Developer Guide LocalCryptoMaterialsCache Results LocalCryptoMaterialsCache Results The following table shows that LocalCryptoMaterialsCache reduces the total calls to KMS (per second per region) in this example to 1% of its original value. Producer requests Requests per second per client No cache Clients per region Average requests per second per region Generate data key (us-west-2) Encrypt data key (eucentral-1) Total (per region) 1 1 1 500 500 1 rps / 100 uses 1 rps / 100 uses 500 5 LocalCryptoMaterialsCache 1 rps / 100 uses 41 AWS Encryption SDK Developer Guide Java Example Consumer requests Requests per second per client No cache Client per region Average requests per second per region Decrypt data key Producers Total 1 rps per producer 500 500 2 1,000 500 5 2 10 LocalCryptoMaterialsCache 1 rps per producer / 100 uses Data Key Caching Example in Java This code sample creates a basic implementation of data key caching with a LocalCryptoMaterialsCache (p. 38) in Java. For details about the Java implementation of the AWS Encryption SDK, see AWS Encryption SDK for Java (p. 13). The code creates two instances of a LocalCryptoMaterialsCache; one for data producers that are encrypting data and another for data consumers (Lambda functions) that are decrypting data. For implementation details, see the Javadoc for the AWS Encryption SDK. Producer The producer gets a map, converts it to JSON, uses the AWS Encryption SDK to encrypt it, and pushes the ciphertext record to a Kinesis stream in each region. The code defines a caching cryptographic materials manager (p. 39) (caching CMM) and associates it with a LocalCryptoMaterialsCache (p. 38) and an underlying KMS master key provider (p. 7). The caching CMM caches the data keys (and related cryptographic materials (p. 39)) from the master key provider. It also interacts with the cache on behalf of the SDK and enforces security thresholds that you set. Because the call to the encryptData method specifies a caching CMM, instead of a regular cryptographic materials manager (CMM) (p. 7) or master key provider, the method will use data key caching. /* * 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.kinesisdatakeycaching; import import import import import java.nio.ByteBuffer; java.util.ArrayList; java.util.HashMap; java.util.List; java.util.Map; 42 AWS Encryption SDK Developer Guide Java Example import java.util.UUID; import java.util.concurrent.TimeUnit; import import import import import import import import import import import import import import com.amazonaws.ClientConfiguration; com.amazonaws.auth.DefaultAWSCredentialsProviderChain; com.amazonaws.encryptionsdk.AwsCrypto; com.amazonaws.encryptionsdk.CryptoResult; com.amazonaws.encryptionsdk.MasterKeyProvider; com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager; com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache; com.amazonaws.encryptionsdk.kms.KmsMasterKey; com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider; com.amazonaws.encryptionsdk.multi.MultipleProviderFactory; com.amazonaws.regions.Region; com.amazonaws.services.kinesis.AmazonKinesis; com.amazonaws.services.kinesis.AmazonKinesisClientBuilder; com.amazonaws.util.json.Jackson; /** * Pushes data to Kinesis Streams in multiple regions. */ public class MultiRegionRecordPusher { private static long MAX_ENTRY_AGE_MILLISECONDS = 300000; private static long MAX_ENTRY_USES = 100; private static int MAX_CACHE_ENTRIES = 100; private final String streamName_; private ArrayList kinesisClients_; private CachingCryptoMaterialsManager cachingMaterialsManager_; private AwsCrypto crypto_; /** * Creates an instance of this object with Kinesis clients for all target regions * and a cached key provider containing KMS master keys in all target regions. */ public MultiRegionRecordPusher(final Region[] regions, final String kmsAliasName, final String streamName){ streamName_ = streamName; crypto_ = new AwsCrypto(); kinesisClients_ = new ArrayList (); DefaultAWSCredentialsProviderChain credentialsProvider = new DefaultAWSCredentialsProviderChain(); ClientConfiguration clientConfig = new ClientConfiguration(); // Build KmsMasterKey and AmazonKinesisClient objects for each target region List masterKeys = new ArrayList (); for (Region region : regions) { kinesisClients_.add(AmazonKinesisClientBuilder.standard() .withCredentials(credentialsProvider) .withRegion(region.getName()) .build()); KmsMasterKey regionMasterKey = new KmsMasterKeyProvider( credentialsProvider, region, clientConfig, kmsAliasName ).getMasterKey(kmsAliasName); } masterKeys.add(regionMasterKey); // Collect KmsMasterKey objects into single provider and add cache MasterKeyProvider masterKeyProvider = MultipleProviderFactory.buildMultiProvider( KmsMasterKey.class, 43 AWS Encryption SDK Developer Guide Java Example ); } masterKeys cachingMaterialsManager_ = CachingCryptoMaterialsManager.newBuilder() .withMasterKeyProvider(masterKeyProvider) .withCache(new LocalCryptoMaterialsCache(MAX_CACHE_ENTRIES)) .withMaxAge(MAX_ENTRY_AGE_MILLISECONDS, TimeUnit.MILLISECONDS) .withMessageUseLimit(MAX_ENTRY_USES) .build(); /** * JSON serializes and encrypts the received record data and pushes it to all target streams. */ public void putRecord(final Map
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf Linearized : No Author : AWS Create Date : 2017:11:09 00:44:31Z Keywords : client-side encryption, encryption client, encryption SDK Modify Date : 2018:01:15 12:40:42+05:30 Has XFA : No XMP Toolkit : Adobe XMP Core 5.6-c015 84.159810, 2016/09/10-02:41:30 Producer : Apache FOP Version 2.1 PDF Version : 1.4 Format : application/pdf Creator : AWS Title : AWS Encryption SDK - Developer Guide Language : en Date : 2017:11:09 00:44:31Z Creator Tool : ZonBook XSL Stylesheets with Apache FOP Metadata Date : 2018:01:15 12:40:42+05:30 Document ID : uuid:059b0115-cf7e-674e-b214-65b857bea5ef Instance ID : uuid:4134ef57-f4ec-a34f-96f6-0f8db4c38e91 Page Mode : UseOutlines Page Count : 78 Profile CMM Type : Unknown (lcms) Profile Version : 2.1.0 Profile Class : Display Device Profile Color Space Data : RGB Profile Connection Space : XYZ Profile Date Time : 1998:02:09 06:49:00 Profile File Signature : acsp Primary Platform : Apple Computer Inc. CMM Flags : Not Embedded, Independent Device Manufacturer : Hewlett-Packard Device Model : sRGB Device Attributes : Reflective, Glossy, Positive, Color Rendering Intent : Perceptual Connection Space Illuminant : 0.9642 1 0.82491 Profile Creator : Unknown (lcms) Profile ID : 0 Profile Copyright : Copyright (c) 1998 Hewlett-Packard Company Profile Description : sRGB IEC61966-2.1 Media White Point : 0.95045 1 1.08905 Media Black Point : 0 0 0 Red Matrix Column : 0.43607 0.22249 0.01392 Green Matrix Column : 0.38515 0.71687 0.09708 Blue Matrix Column : 0.14307 0.06061 0.7141 Device Mfg Desc : IEC http://www.iec.ch Device Model Desc : IEC 61966-2.1 Default RGB colour space - sRGB Viewing Cond Desc : Reference Viewing Condition in IEC61966-2.1 Viewing Cond Illuminant : 19.6445 20.3718 16.8089 Viewing Cond Surround : 3.92889 4.07439 3.36179 Viewing Cond Illuminant Type : D50 Luminance : 76.03647 80 87.12462 Measurement Observer : CIE 1931 Measurement Backing : 0 0 0 Measurement Geometry : Unknown Measurement Flare : 0.999% Measurement Illuminant : D65 Technology : Cathode Ray Tube Display Red Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract) Green Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract) Blue Tone Reproduction Curve : (Binary data 2060 bytes, use -b option to extract)EXIF Metadata provided by EXIF.tools