

# Cryptographic materials provider
<a name="crypto-materials-providers"></a>

**Note**  
Our client-side encryption library was [renamed to AWS Database Encryption SDK](DDBEC-rename.md). The following topic provides information on versions 1.*x*—2.*x* of the DynamoDB Encryption Client for Java and versions 1.*x*—3.*x* of the DynamoDB Encryption Client for Python. For more information, see [AWS Database Encryption SDK for DynamoDB version support](legacy-dynamodb-encryption-client.md#legacy-support).

One of the most important decisions you make when using the DynamoDB Encryption Client is selecting a [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP). The CMP assembles and returns cryptographic materials to the item encryptor. It also determines how encryption and signing keys are generated, whether new key materials are generated for each item or are reused, and the encryption and signing algorithms that are used. 

You can choose a CMP from the implementations provided in the DynamoDB Encryption Client libraries or build a compatible custom CMP. Your CMP choice might also depend on the [programming language](programming-languages.md) that you use.

This topic describes the most common CMPs and offers some advice to help you choose the best one for your application.

**Direct KMS Materials Provider**  
The Direct KMS Materials Provider protects your table items under an [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) that never leaves [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) unencrypted. Your application doesn't have to generate or manage any cryptographic materials. Because it uses the AWS KMS key to generate unique encryption and signing keys for each item, this provider calls AWS KMS every time it encrypts or decrypts an item.   
If you use AWS KMS and one AWS KMS call per transaction is practical for your application, this provider is a good choice.  
For details, see [Direct KMS Materials Provider](direct-kms-provider.md).

**Wrapped Materials Provider (Wrapped CMP)**  
The Wrapped Materials Provider (Wrapped CMP) lets you generate and manage your wrapping and signing keys outside of the DynamoDB Encryption Client.   
The Wrapped CMP generates a unique encryption key for each item. Then it uses wrapping (or unwrapping) and signing keys that you supply. As such, you determine how the wrapping and signing keys are generated and whether they are unique to each item or are reused. The Wrapped CMP is a secure alternative to the [Direct KMS Provider](direct-kms-provider.md) for applications that don't use AWS KMS and can safely manage cryptographic materials.  
For details, see [Wrapped Materials Provider](wrapped-provider.md).

**Most Recent Provider**  
The *Most Recent Provider* is a [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) that is designed to work with a [provider store](DDBEC-legacy-concepts.md#provider-store). It gets CMPs from the provider store, and gets the cryptographic materials that it returns from the CMPs. The Most Recent Provider typically uses each CMP to satisfy multiple requests for cryptographic materials, but you can use the features of the provider store to control the extent to which materials are reused, determine how often its CMP is rotated, and even change the type of CMP that is used without changing the Most Recent Provider.  
You can use the Most Recent Provider with any compatible provider store. The DynamoDB Encryption Client includes a MetaStore, which is a provider store that returns Wrapped CMPs.  
The Most Recent Provider is a good choice for applications that need to minimize calls to their cryptographic source, and applications that can reuse some cryptographic materials without violating their security requirements. For example, it allows you to protect your cryptographic materials under an [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) without calling AWS KMS every time you encrypt or decrypt an item.  
For details, see [Most Recent Provider](most-recent-provider.md).

**Static Materials Provider**  
The Static Materials Provider is designed for testing, proof-of-concept demonstrations, and legacy compatibility. It doesn't generate any unique cryptographic materials for each item. It returns the same encryption and signing keys that you supply, and those keys are used directly to encrypt, decrypt, and sign your table items.   
The [Asymmetric Static Provider](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html) in the Java library is not a static provider. It just supplies alternate constructors for the [Wrapped CMP](wrapped-provider.md). It is safe for production use, but you should use the Wrapped CMP directly whenever possible.

**Topics**
+ [Direct KMS Materials Provider](direct-kms-provider.md)
+ [Wrapped Materials Provider](wrapped-provider.md)
+ [Most Recent Provider](most-recent-provider.md)
+ [Static Materials Provider](static-provider.md)

# Direct KMS Materials Provider
<a name="direct-kms-provider"></a>

**Note**  
Our client-side encryption library was [renamed to AWS Database Encryption SDK](DDBEC-rename.md). The following topic provides information on versions 1.*x*—2.*x* of the DynamoDB Encryption Client for Java and versions 1.*x*—3.*x* of the DynamoDB Encryption Client for Python. For more information, see [AWS Database Encryption SDK for DynamoDB version support](legacy-dynamodb-encryption-client.md#legacy-support).

The *Direct KMS Materials Provider* (Direct KMS Provider) protects your table items under an [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) that never leaves [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) unencrypted. This [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) returns a unique encryption key and signing key for every table item. To do so, it calls AWS KMS every time you encrypt or decrypt an item.

If you're processing DynamoDB items at a high frequency and large scale, you might exceed the AWS KMS [requests-per-second limits](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second), causing processing delays. If you need to exceed a limit, create a case in the [AWS Support Center](https://console.aws.amazon.com/support/home). You might also consider using a cryptographic materials provider with limited key reuse, such as the [Most Recent Provider](most-recent-provider.md).

To use the Direct KMS Provider, the caller must have [an AWS account](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/), at least one AWS KMS key, and permission to call the [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) and [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) operations on the AWS KMS key. The AWS KMS key must be a symmetric encryption key; the DynamoDB Encryption Client does not support asymmetric encryption. If you are using a [DynamoDB global table](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html), you might want to specify an [AWS KMS multi-Region key](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html). For details, see [How to use it](#provider-kms-how-to-use).

**Note**  
When you use the Direct KMS Provider, the names and values of your primary key attributes appear in plaintext in the [AWS KMS encryption context](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context) and AWS CloudTrail logs of related AWS KMS operations. However, the DynamoDB Encryption Client never exposes the plaintext of any encrypted attribute values.

The Direct KMS Provider is one of several [cryptographic materials providers](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) that the DynamoDB Encryption Client supports. For information about the other CMPs, see [Cryptographic materials provider](crypto-materials-providers.md).

**For example code, see:**
+ Java: [AwsKmsEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)
+ Python: [aws-kms-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py), [aws-kms-encrypted-item](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

**Topics**
+ [How to use it](#provider-kms-how-to-use)
+ [How it works](#provider-kms-how-it-works)

## How to use it
<a name="provider-kms-how-to-use"></a>

To create a Direct KMS Provider, use the key ID parameter to specify a symmetric encryption [KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in your account. The value of the key ID parameter can be the key ID, key ARN, alias name, or alias ARN of the AWS KMS key. For details about the key identifiers, see [Key identifiers](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) in the *AWS Key Management Service Developer Guide*.

The Direct KMS Provider requires a symmetric encryption KMS key. You cannot use an asymmetric KMS key. However, you can use a multi-Region KMS key, a KMS key with imported key material, or a KMS key in a custom key store. You must have [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) and [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) permission on the KMS key. As such, you must use a customer managed key, not an AWS managed or AWS owned KMS key.

The DynamoDB Encryption Client for Python determines the Region for calling AWS KMS from the Region in the key ID parameter value, if it includes one. Otherwise, it uses the Region in the AWS KMS client, if you specify one, or the Region that you configure in the AWS SDK for Python (Boto3). For information about Region selection in Python, see [Configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html) in the AWS SDK for Python (Boto3) API Reference.

The DynamoDB Encryption Client for Java determines the Region for calling AWS KMS from the Region in the AWS KMS client, if the client you specify includes a Region. Otherwise, it uses the Region that you configure in the AWS SDK for Java. For information about Region selection in the AWS SDK for Java, see [AWS Region selection](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html) in the AWS SDK for Java Developer Guide.

------
#### [ Java ]

```
// Replace the example key ARN and Region with valid values for your application
final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
final String region = 'us-west-2'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
```

------
#### [ Python ]

The following example uses the key ARN to specify the AWS KMS key. If your key identifier doesn't include an AWS Region, the DynamoDB Encryption Client gets the Region from the configured Botocore session, if there is one, or from Boto defaults.

```
# Replace the example key ID with a valid value
kms_key = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key)
```

------

If you are using [Amazon DynamoDB global tables](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html), we recommend that you encrypt your data under an AWS KMS multi-Region key. Multi-Region keys are AWS KMS keys in different AWS Regions that can be used interchangeably because they have the same key ID and key material. For details, see [Using multi-Region keys](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html) in the *AWS Key Management Service Developer Guide*.

**Note**  
If you are using the global tables [version 2017.11.29](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html), you must set attribute actions so the reserved replication fields are not encrypted or signed. For details, see [Issues with older version global tables](troubleshooting.md#fix-global-tables).

To use a multi-Region key with the DynamoDB Encryption Client, create a multi-Region key and replicate it into the Regions in which your application runs. Then configure the Direct KMS Provider to use the multi-Region key in the Region in which the DynamoDB Encryption Client calls AWS KMS.

The following example configures the DynamoDB Encryption Client to encrypt data in the US East (N. Virginia) (us-east-1) Region and decrypt it in the US West (Oregon) (us-west-2) Region using a multi-Region key.

------
#### [ Java ]

In this example, the DynamoDB Encryption Client gets the Region for calling AWS KMS from the Region in the AWS KMS client. The `keyArn` value identifies a multi-Region key in the same Region.

```
// Encrypt in us-east-1

// Replace the example key ARN and Region with valid values for your application
final String usEastKey = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-east-1'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usEastKey);
```

```
// Decrypt in us-west-2

// Replace the example key ARN and Region with valid values for your application
final String usWestKey = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-west-2'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usWestKey);
```

------
#### [ Python ]

In this example, the DynamoDB Encryption Client gets the Region for calling AWS KMS from the Region in the key ARN.

```
# Encrypt in us-east-1

# Replace the example key ID with a valid value
us_east_key = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_east_key)
```

```
# Decrypt in us-west-2

# Replace the example key ID with a valid value
us_west_key = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_west_key)
```

------

## How it works
<a name="provider-kms-how-it-works"></a>

The Direct KMS Provider returns encryption and signing keys that are protected by an AWS KMS key that you specify, as shown in the following diagram.

![\[The input, processing, and output of the Direct KMS Provider in the DynamoDB Encryption Client\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/directKMS.png)

+ To generate encryption materials, the Direct KMS Provider asks AWS KMS to [generate a unique data key](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) for each item using an AWS KMS key that you specify. It derives encryption and signing keys for the item from the plaintext copy of the [data key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys), and then returns the encryption and signing keys, along with the encrypted data key, which is stored in the [material description attribute](DDBEC-legacy-concepts.md#legacy-material-description) of the item. 

  The item encryptor uses the encryption and signing keys and removes them from memory as soon as possible. Only the encrypted copy of the data key from which they were derived is saved in the encrypted item.
+ To generate decryption materials, the Direct KMS Provider asks AWS KMS to decrypt the encrypted data key. Then, it derives verification and signing keys from the plaintext data key, and returns them to the item encryptor.

  The item encryptor verifies the item and, if verification succeeds, decrypts the encrypted values. Then, it removes the keys from memory as soon as possible.

### Get encryption materials
<a name="direct-kms-get-encryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Direct KMS Provider when it receives a request for encryption materials from the [item encryptor](DDBEC-legacy-concepts.md#item-encryptor).

**Input ** (from the application)
+ The key ID of an AWS KMS key. 

**Input** (from the item encryptor)
+ [DynamoDB encryption context](concepts.md#encryption-context)

**Output** (to the item encryptor)
+ Encryption key (plaintext)
+ Signing key
+ In [actual material description](DDBEC-legacy-concepts.md#legacy-material-description): These values are saved in the material description attribute that the client adds to the item.
  + amzn-ddb-env-key: Base64-encoded data key encrypted by the AWS KMS key
  + amzn-ddb-env-alg: Encryption algorithm, by default [AES/256](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/archived-crypto-projects/aes-development)
  + amzn-ddb-sig-alg: Signing algorithm, by default, [HmacSHA256/256](https://en.wikipedia.org/wiki/HMAC)
  + amzn-ddb-wrap-alg: kms

**Processing**

1. The Direct KMS Provider sends AWS KMS a request to use the specified AWS KMS key to [generate a unique data key](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) for the item. The operation returns a plaintext key and a copy that is encrypted under the AWS KMS key. This is known as the *initial key material*.

   The request includes the following values in plaintext in [AWS KMS encryption context](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context). These non-secret values are cryptographically bound to the encrypted object, so the same encryption context is required on decrypt. You can use these values to identify the call to AWS KMS in [AWS CloudTrail logs](https://docs.aws.amazon.com/kms/latest/developerguide/monitoring-overview.html).
   + amzn-ddb-env-alg – Encryption algorithm, by default AES/256
   + amzn-ddb-sig-alg – Signing algorithm, by default HmacSHA256/256
   + (Optional) aws-kms-table – *table name*
   + (Optional) *partition key name* – *partition key value* (binary values are Base64-encoded)
   + (Optional) *sort key name* – *sort key value* (binary values are Base64-encoded)

   The Direct KMS Provider gets the values for the AWS KMS encryption context from the [DynamoDB encryption context](concepts.md#encryption-context) for the item. If the DynamoDB encryption context doesn't include a value, such as the table name, that name-value pair is omitted from the AWS KMS encryption context.

1. The Direct KMS Provider derives a symmetric encryption key and a signing key from the data key. By default, it uses [Secure Hash Algorithm (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) and [RFC5869 HMAC-based Key Derivation Function](https://tools.ietf.org/html/rfc5869) to derive a 256-bit AES symmetric encryption key and a 256-bit HMAC-SHA-256 signing key. 

1. The Direct KMS Provider returns the output to the item encryptor.

1. The item encryptor uses the encryption key to encrypt the specified attributes and the signing key to sign them, using the algorithms specified in the actual material description. It removes the plaintext keys from memory as soon as possible.

### Get decryption materials
<a name="direct-kms-get-decryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Direct KMS Provider when it receives a request for decryption materials from the [item encryptor](DDBEC-legacy-concepts.md#item-encryptor).

**Input ** (from the application)
+ The key ID of an AWS KMS key. 

  The value of the key ID can be the key ID, key ARN, alias name or alias ARN of the AWS KMS key. Any values that aren't included in the key ID, such as the Region, must be available in the [AWS named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles). The key ARN provides all of the values that AWS KMS needs.

**Input** (from the item encryptor)
+ A copy of the [DynamoDB encryption context](concepts.md#encryption-context) that contains the contents of the material description attribute.

**Output** (to the item encryptor)
+ Encryption key (plaintext)
+ Signing key

**Processing**

1. The Direct KMS Provider gets the encrypted data key from the material description attribute in the encrypted item. 

1. It asks AWS KMS to use the specified AWS KMS key to [decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) the encrypted data key. The operation returns a plaintext key.

   This request must use the same [AWS KMS encryption context](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context) that was used to generate and encrypt the data key.
   + aws-kms-table – *table name*
   + *partition key name* – *partition key value* (binary values are Base64-encoded)
   + (Optional) *sort key name* – *sort key value* (binary values are Base64-encoded)
   + amzn-ddb-env-alg – Encryption algorithm, by default AES/256
   + amzn-ddb-sig-alg – Signing algorithm, by default HmacSHA256/256

1. The Direct KMS Provider uses [Secure Hash Algorithm (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) and [RFC5869 HMAC-based Key Derivation Function](https://tools.ietf.org/html/rfc5869) to derive a 256-bit AES symmetric encryption key and a 256-bit HMAC-SHA-256 signing key from the data key. 

1. The Direct KMS Provider returns the output to the item encryptor.

1. The item encryptor uses the signing key to verify the item. If it succeeds, it uses the symmetric encryption key to decrypt the encrypted attribute values. These operations use the encryption and signing algorithms specified in the actual material description. The item encryptor removes the plaintext keys from memory as soon as possible.

# Wrapped Materials Provider
<a name="wrapped-provider"></a>

**Note**  
Our client-side encryption library was [renamed to AWS Database Encryption SDK](DDBEC-rename.md). The following topic provides information on versions 1.*x*—2.*x* of the DynamoDB Encryption Client for Java and versions 1.*x*—3.*x* of the DynamoDB Encryption Client for Python. For more information, see [AWS Database Encryption SDK for DynamoDB version support](legacy-dynamodb-encryption-client.md#legacy-support).

The *Wrapped Materials Provider* (Wrapped CMP) lets you use wrapping and signing keys from any source with the DynamoDB Encryption Client. The Wrapped CMP does not depend on any AWS service. However, you must generate and manage your wrapping and signing keys outside of the client, including providing the correct keys to verify and decrypt the item. 

The Wrapped CMP generates a unique item encryption key for each item. It wraps the item encryption key with the wrapping key that you provide and saves the wrapped item encryption key in the [material description attribute](DDBEC-legacy-concepts.md#legacy-material-description) of the item. Because you supply the wrapping and signing keys, you determine how the wrapping and signing keys are generated and whether they are unique to each item or are reused. 

The Wrapped CMP is a secure implementation and a good choice for applications that can manage cryptographic materials.

The Wrapped CMP is one of several [cryptographic materials providers](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) that the DynamoDB Encryption Client supports. For information about the other CMPs, see [Cryptographic materials provider](crypto-materials-providers.md).

**For example code, see:**
+ Java: [AsymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AsymmetricEncryptedItem.java)
+ Python: [wrapped-rsa-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_rsa_encrypted_table.py), [wrapped-symmetric-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_symmetric_encrypted_table.py)

**Topics**
+ [How to use it](#wrapped-cmp-how-to-use)
+ [How it works](#wrapped-cmp-how-it-works)

## How to use it
<a name="wrapped-cmp-how-to-use"></a>

To create a Wrapped CMP, specify a wrapping key (required on encrypt), an unwrapping key (required on decrypt), and a signing key. You must supply keys when you encrypt and decrypt items.

The wrapping, unwrapping, and signing keys can be symmetric keys or asymmetric key pairs. 

------
#### [ Java ]

```
// This example uses asymmetric wrapping and signing key pairs
final KeyPair wrappingKeys = ...
final KeyPair signingKeys = ...

final WrappedMaterialsProvider cmp = 
    new WrappedMaterialsProvider(wrappingKeys.getPublic(),
                                 wrappingKeys.getPrivate(),
                                 signingKeys);
```

------
#### [ Python ]

```
# This example uses symmetric wrapping and signing keys
wrapping_key = ...
signing_key  = ...

wrapped_cmp = WrappedCryptographicMaterialsProvider(
    wrapping_key=wrapping_key,
    unwrapping_key=wrapping_key,
    signing_key=signing_key
)
```

------

## How it works
<a name="wrapped-cmp-how-it-works"></a>

The Wrapped CMP generates a new item encryption key for every item. It uses the wrapping, unwrapping, and signing keys that you provide, as shown in the following diagram.

![\[The input, processing, and output of the Wrapped Materials Provider in the DynamoDB Encryption Client\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/wrappedCMP.png)


### Get encryption materials
<a name="wrapped-cmp-get-encryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Wrapped Materials Provider (Wrapped CMP) when it receives a request for encryption materials. 

**Input** (from application)
+ Wrapping key: An [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) symmetric key, or an [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) public key. Required if any attribute values are encrypted. Otherwise, it is optional and ignored.
+ Unwrapping key: Optional and ignored. 
+ Signing key

**Input** (from the item encryptor)
+ [DynamoDB encryption context](concepts.md#encryption-context)

**Output** (to the item encryptor):
+ Plaintext item encryption key
+ Signing key (unchanged)
+ [Actual material description](DDBEC-legacy-concepts.md#legacy-material-description): These values are saved in the [material description attribute](DDBEC-legacy-concepts.md#legacy-material-description) that the client adds to the item. 
  + `amzn-ddb-env-key`: Base64-encoded wrapped item encryption key
  + `amzn-ddb-env-alg`: Encryption algorithm used to encrypt the item. The default is AES-256-CBC.
  + `amzn-ddb-wrap-alg`: The wrapping algorithm that the Wrapped CMP used to wrap the item encryption key. If the wrapping key is an AES key, the key is wrapped using unpadded `AES-Keywrap` as defined in [RFC 3394](https://tools.ietf.org/html/rfc3394.html). If the wrapping key is an RSA key, the key is encrypted by using RSA OAEP with MGF1 padding. 

**Processing**

When you encrypt an item, you pass in a wrapping key and a signing key. An unwrapping key is optional and ignored.

1. The Wrapped CMP generates a unique symmetric item encryption key for the table item.

1. It uses the wrapping key that you specify to wrap the item encryption key. Then, it removes it from memory as soon as possible.

1. It returns the plaintext item encryption key, the signing key that you supplied, and an [actual material description](DDBEC-legacy-concepts.md#legacy-material-description) that includes the wrapped item encryption key, and the encryption and wrapping algorithms.

1. The item encryptor uses the plaintext encryption key to encrypt the item. It uses the signing key that you supplied to sign the item. Then, it removes the plaintext keys from memory as soon as possible. It copies the fields in the actual material description, including the wrapped encryption key (`amzn-ddb-env-key`), to the material description attribute of the item.

### Get decryption materials
<a name="wrapped-cmp-get-decryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Wrapped Materials Provider (Wrapped CMP) when it receives a request for decryption materials. 

**Input** (from application)
+ Wrapping key: Optional and ignored.
+ Unwrapping key: The same [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) symmetric key or [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) private key that corresponds to the RSA public key used to encrypt. Required if any attribute values are encrypted. Otherwise, it is optional and ignored.
+ Signing key

**Input** (from the item encryptor)
+ A copy of the [DynamoDB encryption context](concepts.md#encryption-context) that contains the contents of the material description attribute.

**Output** (to the item encryptor)
+ Plaintext item encryption key
+ Signing key (unchanged)

**Processing**

When you decrypt an item, you pass in an unwrapping key and a signing key. A wrapping key is optional and ignored.

1. The Wrapped CMP gets the wrapped item encryption key from the material description attribute of the item.

1. It uses the unwrapping key and algorithm to unwrap the item encryption key. 

1. It returns the plaintext item encryption key, the signing key, and encryption and signing algorithms to the item encryptor.

1. The item encryptor uses the signing key to verify the item. If it succeeds, it uses the item encryption key to decrypt the item. Then, it removes the plaintext keys from memory as soon as possible.

# Most Recent Provider
<a name="most-recent-provider"></a>

**Note**  
Our client-side encryption library was [renamed to AWS Database Encryption SDK](DDBEC-rename.md). The following topic provides information on versions 1.*x*—2.*x* of the DynamoDB Encryption Client for Java and versions 1.*x*—3.*x* of the DynamoDB Encryption Client for Python. For more information, see [AWS Database Encryption SDK for DynamoDB version support](legacy-dynamodb-encryption-client.md#legacy-support).

The *Most Recent Provider* is a [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) that is designed to work with a [provider store](DDBEC-legacy-concepts.md#provider-store). It gets CMPs from the provider store, and gets the cryptographic materials that it returns from the CMPs. It typically uses each CMP to satisfy multiple requests for cryptographic materials. But you can use the features of its provider store to control the extent to which materials are reused, determine how often its CMP is rotated, and even change the type of CMP that it uses without changing the Most Recent Provider.

**Note**  
The code associated with the `MostRecentProvider` symbol for the Most Recent Provider might store cryptographic materials in memory for the lifetime of the process. It might allow a caller to use keys that they're no longer authorized to use.   
The `MostRecentProvider` symbol is deprecated in older supported versions of the DynamoDB Encryption Client and removed from version 2.0.0. It is replaced by the `CachingMostRecentProvider` symbol. For details, see [Updates to the Most Recent Provider](#mrp-versions).

The Most Recent Provider is a good choice for applications that need to minimize calls to the provider store and its cryptographic source, and applications that can reuse some cryptographic materials without violating their security requirements. For example, It allows you to protect your cryptographic materials under an [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) without calling AWS KMS every time you encrypt or decrypt an item.

The provider store that you choose determines the type of CMPs that the Most Recent Provider uses and how often it gets a new CMP. You can use any compatible provider store with the Most Recent Provider, including custom provider stores that you design. 

The DynamoDB Encryption Client includes a *MetaStore* that creates and returns [Wrapped Materials Providers](wrapped-provider.md) (Wrapped CMPs). The MetaStore saves multiple versions of the Wrapped CMPs that it generates in an internal DynamoDB table and protects them with client-side encryption by an internal instance of the DynamoDB Encryption Client. 

You can configure the MetaStore to use any type of internal CMP to protect the materials in the table, including a [Direct KMS Provider](direct-kms-provider.md) that generates cryptographic materials protected by your AWS KMS key, a Wrapped CMP that uses wrapping and signing keys that you supply, or a compatible custom CMP that you design.

**For example code, see:**
+ Java: [MostRecentEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/MostRecentEncryptedItem.java)
+ Python: [most\$1recent\$1provider\$1encrypted\$1table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/most_recent_provider_encrypted_table.py)

**Topics**
+ [How to use it](#mrp-how-to-use-it)
+ [How it works](#mrp-how-it-works)
+ [Updates to the Most Recent Provider](#mrp-versions)

## How to use it
<a name="mrp-how-to-use-it"></a>

To create a Most Recent Provider, you need to create and configure a provider store, and then create a Most Recent Provider that uses the provider store. 

The following examples show how to create a Most Recent Provider that uses a MetaStore and protects the versions in its internal DynamoDB table with cryptographic materials from a [Direct KMS Provider](direct-kms-provider.md). These examples use the [`CachingMostRecentProvider`](#mrp-versions) symbol. 

Each Most Recent Provider has a name that identifies its CMPs in the MetaStore table, a [time-to-live](#most-recent-provider-ttl) (TTL) setting, and a cache size setting that determines how many entries the cache can hold. These examples set the cache size to 1000 entries and a TTL of 60 seconds.

------
#### [ Java ]

```
// Set the name for MetaStore's internal table
final String keyTableName = 'metaStoreTable'

// Set the Region and AWS KMS key
final String region = 'us-west-2'
final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

// Set the TTL and cache size
final long ttlInMillis = 60000;
final long cacheSize = 1000;

// Name that identifies the MetaStore's CMPs in the provider store
final String materialName = 'testMRP'

// Create an internal DynamoDB client for the MetaStore
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();

// Create an internal Direct KMS Provider for the MetaStore
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider kmsProv = new DirectKmsMaterialProvider(kms, keyArn);

// Create an item encryptor for the MetaStore,
// including the Direct KMS Provider
final DynamoDBEncryptor keyEncryptor = DynamoDBEncryptor.getInstance(kmsProv);

// Create the MetaStore
final MetaStore metaStore = new MetaStore(ddb, keyTableName, keyEncryptor);

//Create the Most Recent Provider
final CachingMostRecentProvider cmp = new CachingMostRecentProvider(metaStore, materialName, ttlInMillis, cacheSize);
```

------
#### [ Python ]

```
# Designate an AWS KMS key
kms_key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

# Set the name for MetaStore's internal table
meta_table_name = 'metaStoreTable'

# Name that identifies the MetaStore's CMPs in the provider store
material_name = 'testMRP'

# Create an internal DynamoDB table resource for the MetaStore
meta_table = boto3.resource('dynamodb').Table(meta_table_name)

# Create an internal Direct KMS Provider for the MetaStore
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
    
# Create the MetaStore with the Direct KMS Provider
meta_store = MetaStore(
    table=meta_table,
    materials_provider=kms_cmp
)

# Create a Most Recent Provider using the MetaStore
#    Sets the TTL (in seconds) and cache size (# entries)
most_recent_cmp = MostRecentProvider(
    provider_store=meta_store,
    material_name=material_name,
    version_ttl=60.0,
    cache_size=1000
)
```

------

## How it works
<a name="mrp-how-it-works"></a>

The Most Recent Provider gets CMPs from a provider store. Then, it uses the CMP to generate the cryptographic materials that it returns to the item encryptor.

### About the Most Recent Provider
<a name="about-mrp"></a>

The Most Recent Provider gets a [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) from a [provider store](DDBEC-legacy-concepts.md#provider-store). Then, it uses the CMP to generate the cryptographic materials it returns. Each Most Recent Provider is associated with one provider store, but a provider store can supply CMPs to multiple providers across multiple hosts.

The Most Recent Provider can work with any compatible CMP from any provider store. It requests encryption or decryption materials from the CMP and returns the output to the item encryptor. It does not perform any cryptographic operations.

To request a CMP from its provider store, the Most Recent Provider supplies its material name and the version of an existing CMP it wants to use. For encryption materials, the Most Recent Provider always requests the maximum ("most recent") version. For decryption materials, it requests the version of the CMP that was used to create the encryption materials, as shown in the following diagram.

![\[A Most Recent Provider\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/most-recent-provider-1.png)


The Most Recent Provider saves versions of the CMPs that the provider store returns in a local Least Recently Used (LRU) cache in memory. The cache enables the Most Recent Provider to get the CMPs that it needs without calling the provider store for every item. You can clear the cache on demand.

The Most Recent Provider uses a configurable [time-to-live value](#most-recent-provider-ttl) that you can adjust based on the characteristics of your application.

### About the MetaStore
<a name="about-metastore"></a>

You can use a Most Recent Provider with any provider store, including a compatible custom provider store. The DynamoDB Encryption Client includes a MetaStore, a secure implementation that you can configure and customize.

A *MetaStore* is a [provider store](DDBEC-legacy-concepts.md#provider-store) that creates and returns [Wrapped CMPs](wrapped-provider.md) that are configured with the wrapping key, unwrapping key, and signing key that Wrapped CMPs require. A MetaStore is a secure option for a Most Recent Provider because Wrapped CMPs always generate unique item encryption keys for every item. Only the wrapping key that protects the item encryption key and the signing keys are reused.

The following diagram shows the components of the MetaStore and how it interacts with the Most Recent Provider.

![\[A MetaStore\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/most-recent-provider-2.png)


The MetaStore generates the Wrapped CMPs, and then stores them (in encrypted form) in an internal DynamoDB table. The partition key is the name of the Most Recent Provider material; the sort key its version number. The materials in the table are protected by an internal DynamoDB Encryption Client, including an item encryptor and internal [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP).

You can use any type of internal CMP in your MetaStore, including the a [Direct KMS Provider](wrapped-provider.md), a Wrapped CMP with cryptographic materials that you provide, or a compatible custom CMP. If the internal CMP in your MetaStore is a Direct KMS Provider, your reusable wrapping and signing keys are protected under a [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS). The MetaStore calls AWS KMS every time it adds a new CMP version to its internal table or gets a CMP version from its internal table.

### Setting a time-to-live value
<a name="most-recent-provider-ttl"></a>

You can set a time-to-live (TTL) value for each Most Recent Provider that you create. In general, use the lowest TTL value that is practical for your application.

The use of the TTL value is changed in the `CachingMostRecentProvider` symbol for the Most Recent Provider. 

**Note**  
The `MostRecentProvider` symbol for the Most Recent Provider is deprecated in older supported versions of the DynamoDB Encryption Client and removed from version 2.0.0. It is replaced by the `CachingMostRecentProvider` symbol. We recommend that you update your code as soon as possible. For details, see [Updates to the Most Recent Provider](#mrp-versions).

**`CachingMostRecentProvider`**  
The `CachingMostRecentProvider` uses the TTL value in two different ways.   
+ The TTL determines how often the Most Recent Provider checks the provider store for a new version of the CMP. If a new version is available, the Most Recent Provider replaces its CMP and refreshes its cryptographic materials. Otherwise, it continues to use its current CMP and cryptographic materials.
+ The TTL determines how long CMPs in the cache can be used. Before it uses a cached CMP for encryption, the Most Recent Provider evaluates its time in the cache. If the CMP cache time exceeds the TTL, the CMP is evicted from the cache and the Most Recent Provider gets a new, latest-version CMP from its provider store.

**`MostRecentProvider`**  
In the `MostRecentProvider`, the TTL determines how often the Most Recent Provider checks the provider store for a new version of the CMP. If a new version is available, the Most Recent Provider replaces its CMP and refreshes its cryptographic materials. Otherwise, it continues to use its current CMP and cryptographic materials.

The TTL does not determine how often a new CMP version is created. You create new CMP versions by [rotating the cryptographic materials](#most-recent-provider-rotate).

An ideal TTL value varies with the application and its latency and availability goals. A lower TTL improves your security profile by reducing the time that cryptographic materials are stored in memory. Also, a lower TTL refreshes critical information more frequently. For example, if your internal CMP is a [Direct KMS Provider](direct-kms-provider.md), it verifies more frequently that the caller is still authorized to use an AWS KMS key.

However, if the TTL is too brief, the frequent calls to the provider store can increase your costs and cause your provider store to throttle requests from your application and other applications that share your service account. You might also benefit from coordinating the TTL with the rate at which you rotate cryptographic materials. 

During testing, vary the TTL and cache size under different work loads until you find a configuration that works for your application and your security and performance standards.

### Rotating cryptographic materials
<a name="most-recent-provider-rotate"></a>

When a Most Recent Provider needs encryption materials, it always uses the most recent version of its CMP that it knows about. The frequency that it checks for a newer version is determined by the [time-to-live](#most-recent-provider-ttl) (TTL) value that you set when you configure the Most Recent Provider. 

When the TTL expires, the Most Recent Provider checks the provider store for newer version of the CMP. If one is available, the Most Recent Provider get it and replaces the CMP in its cache. It uses this CMP and its cryptographic materials until it discovers that provider store has a newer version.

To tell the provider store to create a new version of a CMP for a Most Recent Provider, call the provider store's Create New Provider operation with the material name of the Most Recent Provider. The provider store creates a new CMP and saves an encrypted copy in its internal storage with a greater version number. (It also returns a CMP, but you can discard it.) As a result, the next time the Most Recent Provider queries the provider store for the maximum version number of its CMPs, it gets the new greater version number, and uses it in subsequent requests to the store to see if a new version of the CMP has been created.

You can schedule your Create New Provider calls based on time, the number of items or attributes processed, or any other metric that makes sense for your application.

### Get encryption materials
<a name="most-recent-provider-encrypt"></a>

The Most Recent Provider uses the following process, shown in this diagram, to get the encryption materials that it returns to the item encryptor. The output depends on the type of CMP that the provider store returns. The Most Recent Provider can use any compatible provider store, including the MetaStore that is included in the DynamoDB Encryption Client.

![\[Input, processing, and output of the Most Recent Provider in the DynamoDB Encryption Client\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/most-recent-provider-provider-store.png)


When you create a Most Recent Provider by using the [`CachingMostRecentProvider` symbol](#mrp-versions), you specify a provider store, a name for the Most Recent Provider, and a [time-to-live](#most-recent-provider-ttl) (TTL) value. You can also optionally specify a cache size, which determines the maximum number of cryptographic materials that can exist in the cache.

When the item encryptor asks the Most Recent Provider for encryption materials, the Most Recent Provider begins by searching its cache for the latest version of its CMP.
+ If it finds the latest version CMP in its cache and the CMP has not exceeded the TTL value, the Most Recent Provider uses the CMP to generate encryption materials. Then, it returns the encryption materials to the item encryptor. This operation does not require a call to the provider store.
+ If the latest version of the CMP is not in its cache, or if it is in the cache but has exceeded its TTL value, the Most Recent Provider requests a CMP from its provider store. The request includes the Most Recent Provider material name and the maximum version number that it knows.

  1. The provider store returns a CMP from its persistent storage. If the provider store is a MetaStore, it gets an encrypted Wrapped CMP from its internal DynamoDB table by using the Most Recent Provider material name as the partition key and the version number as the sort key. The MetaStore uses its internal item encryptor and internal CMP to decrypt the Wrapped CMP. Then, it returns the plaintext CMP to the Most Recent Provider . If the internal CMP is a [Direct KMS Provider](direct-kms-provider.md), this step includes a call to the [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS).

  1. The CMP adds the `amzn-ddb-meta-id` field to the [actual material description](DDBEC-legacy-concepts.md#legacy-material-description). Its value is the material name and version of the CMP in its internal table. The provider store returns the CMP to the Most Recent Provider.

  1. The Most Recent Provider caches the CMP in memory.

  1. The Most Recent Provider uses the CMP to generate encryption materials. Then, it returns the encryption materials to the item encryptor.

### Get decryption materials
<a name="most-recent-provider-decrypt"></a>

When the item encryptor asks the Most Recent Provider for decryption materials, the Most Recent Provider uses the following process to get and return them.

1. The Most Recent Provider asks the provider store for the version number of the cryptographic materials that were used to encrypt the item. It passes in the actual material description from the [material description attribute](DDBEC-legacy-concepts.md#legacy-material-description) of the item.

1. The provider store gets the encrypting CMP version number from the `amzn-ddb-meta-id` field in the actual material description and returns it to the Most Recent Provider.

1. The Most Recent Provider searches its cache for the version of CMP that was used to encrypt and sign the item.
+ If it finds the matching version of the CMP is in its cache and the CMP has not exceeded the [time-to-live (TTL) value](#most-recent-provider-ttl), the Most Recent Provider uses the CMP to generate decryption materials. Then, it returns the decryption materials to the item encryptor. This operation does not require a call to the provider store or any other CMP.
+ If the matching version of the CMP is not in its cache, or if the cached AWS KMS key has exceeded its TTL value, the Most Recent Provider requests a CMP from its provider store. It sends its material name and the encrypting CMP version number in the request.

  1. The provider store searches its persistent storage for the CMP by using the Most Recent Provider name as the partition key and the version number as the sort key.
     + If the name and version number are not in its persistent storage, the provider store throws an exception. If the provider store was used to generate the CMP, the CMP should be stored in its persistent storage, unless it was intentionally deleted.
     + If the CMP with the matching name and version number are in the provider store's persistent storage, the provider store returns the specified CMP to the Most Recent Provider. 

       If the provider store is a MetaStore, it gets the encrypted CMP from its DynamoDB table. Then, it uses cryptographic materials from its internal CMP to decrypt the encrypted CMP before it returns the CMP to Most Recent Provider. If the internal CMP is a [Direct KMS Provider](direct-kms-provider.md), this step includes a call to the [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS).

  1. The Most Recent Provider caches the CMP in memory.

  1. The Most Recent Provider uses the CMP to generate decryption materials. Then, it returns the decryption materials to the item encryptor.

## Updates to the Most Recent Provider
<a name="mrp-versions"></a>

The symbol for the Most Recent Provider is changed from `MostRecentProvider` to `CachingMostRecentProvider`. 

**Note**  
The `MostRecentProvider` symbol, which represents the Most Recent Provider, is deprecated in version 1.15 of the DynamoDB Encryption Client for Java and version 1.3 of the DynamoDB Encryption Client for Python and removed from versions 2.0.0 of the DynamoDB Encryption Client in both language implementations. Instead, use the `CachingMostRecentProvider`.

The `CachingMostRecentProvider` implements the following changes:
+ The `CachingMostRecentProvider` periodically removes cryptographic materials from memory when their time in memory exceeds the configured [time-to-live (TTL) value](#most-recent-provider-ttl). 

  The `MostRecentProvider` might store cryptographic materials in memory for the lifetime of the process. As a result, the Most Recent Provider might not be aware of authorization changes. It might use encryption keys after the caller's permissions to use them are revoked. 

  If you can't update to this new version, you can get a similar effect by periodically calling the `clear()` method on the cache. This method manually flushes the cache contents and requires the Most Recent Provider to request a new CMP and new cryptographic materials. 
+ The `CachingMostRecentProvider` also includes a cache size setting that gives you more control over the cache.

To update to the `CachingMostRecentProvider`, you have to change the symbol name in your code. In all other respects, the `CachingMostRecentProvider` is fully backwards compatible with the `MostRecentProvider`. You don't need to re-encrypt any table items.

However, the `CachingMostRecentProvider` generates more calls to the underlying key infrastructure. It calls the provider store at least once in each time-to-live (TTL) interval. Applications with numerous active CMPs (due to frequent rotation) or applications with large fleets are most likely to be sensitive to this change. 

Before releasing your updated code, test it thoroughly to ensure that the more frequent calls don't impair your application or cause throttling by services on which your provider depends, such as AWS Key Management Service (AWS KMS) or Amazon DynamoDB. To mitigate any performance problems, adjust the cache size and the time-to-live of the `CachingMostRecentProvider` based on the performance characteristics you observe. For guidance, see [Setting a time-to-live value](#most-recent-provider-ttl).

# Static Materials Provider
<a name="static-provider"></a>

**Note**  
Our client-side encryption library was [renamed to AWS Database Encryption SDK](DDBEC-rename.md). The following topic provides information on versions 1.*x*—2.*x* of the DynamoDB Encryption Client for Java and versions 1.*x*—3.*x* of the DynamoDB Encryption Client for Python. For more information, see [AWS Database Encryption SDK for DynamoDB version support](legacy-dynamodb-encryption-client.md#legacy-support).

The *Static Materials Provider* (Static CMP) is a very simple [cryptographic materials provider](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) that is intended for testing, proof-of-concept demonstrations, and legacy compatibility.

To use the Static CMP to encrypt a table item, you supply an [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) symmetric encryption key and a signing key or key pair. You must supply the same keys to decrypt the encrypted item. The Static CMP does not perform any cryptographic operations. Instead, it passes the encryption keys that you supply to the item encryptor unchanged. The item encryptor encrypts the items directly under the encryption key. Then, it uses the signing key directly to sign them. 

Because the Static CMP does not generate any unique cryptographic materials, all table items that you process are encrypted with the same encryption key and signed by the same signing key. When you use the same key to encrypt the attributes values in numerous items or use the same key or key pair to sign all items, you risk exceeding the cryptographic limits of the keys. 

**Note**  
The [Asymmetric Static Provider](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html) in the Java library is not a static provider. It just supplies alternate constructors for the [Wrapped CMP](wrapped-provider.md). It's safe for production use, but you should use the Wrapped CMP directly whenever possible.

The Static CMP is one of several [cryptographic materials providers](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) that the DynamoDB Encryption Client supports. For information about the other CMPs, see [Cryptographic materials provider](crypto-materials-providers.md).

**For example code, see:**
+ Java: [SymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/SymmetricEncryptedItem.java)

**Topics**
+ [How to use it](#static-cmp-how-to-use)
+ [How it works](#static-cmp-how-it-works)

## How to use it
<a name="static-cmp-how-to-use"></a>

To create a static provider, supply an encryption key or key pair and a signing key or key pair. You need to provide key material to encrypt and decrypt table items.

------
#### [ Java ]

```
// To encrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Signing key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);

// To decrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Verification key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);
```

------
#### [ Python ]

```
# You can provide encryption materials, decryption materials, or both
encrypt_keys = EncryptionMaterials(
    encryption_key = ...,
    signing_key = ...
)

decrypt_keys = DecryptionMaterials(
    decryption_key = ...,
    verification_key = ...
)

static_cmp = StaticCryptographicMaterialsProvider(
    encryption_materials=encrypt_keys
    decryption_materials=decrypt_keys
)
```

------

## How it works
<a name="static-cmp-how-it-works"></a>

The Static Provider passes the encryption and signing keys that you supply to the item encryptor, where they are used directly to encrypt and sign your table items. Unless you supply different keys for each item, the same keys are used for every item.

![\[The input, processing, and output of the Static Materials Provider in the DynamoDB Encryption Client\]](http://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/images/staticCMP.png)


### Get encryption materials
<a name="static-cmp-get-encryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Static Materials Provider (Static CMP) when it receives a request for encryption materials.

**Input** (from the application)
+ An encryption key – This must be a symmetric key, such as an [Advanced Encryption Standard](https://tools.ietf.org/html/rfc3394.html) (AES) key. 
+ A signing key – This can be a symmetric key or an asymmetric key pair. 

**Input** (from the item encryptor)
+ [DynamoDB encryption context](concepts.md#encryption-context)

**Output** (to the item encryptor)
+ The encryption key passed as input.
+ The signing key passed as input.
+ Actual material description: The [requested material description](DDBEC-legacy-concepts.md#legacy-material-description), if any, unchanged.

### Get decryption materials
<a name="static-cmp-get-decryption-materials"></a>

This section describes in detail the inputs, outputs, and processing of the Static Materials Provider (Static CMP) when it receives a request for decryption materials.

Although it includes separate methods for getting encryption materials and getting decryption materials, the behavior is the same. 

**Input** (from the application)
+ An encryption key – This must be a symmetric key, such as an [Advanced Encryption Standard](https://tools.ietf.org/html/rfc3394.html) (AES) key. 
+ A signing key – This can be a symmetric key or an asymmetric key pair. 

**Input** (from the item encryptor)
+ [DynamoDB encryption context](concepts.md#encryption-context) (not used)

**Output** (to the item encryptor)
+ The encryption key passed as input.
+ The signing key passed as input.