

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 最新提供程序
<a name="most-recent-provider"></a>

**注意**  
我们的客户端加密库已[重命名为 AWS 数据库加密 SDK](DDBEC-rename.md)。以下主题提供有关适用于 Java 的 DynamoDB 加密客户端版本 1.*x*—2.*x* 以及适用于 Python 的 DynamoDB 加密客户端版本 1.*x*—3.*x* 的信息。有关更多信息，请参阅[适用于 DynamoDB 的AWS 数据库加密 SDK 版本支持](legacy-dynamodb-encryption-client.md#legacy-support)。

*最新提供程序*是一个[加密材料提供程序](DDBEC-legacy-concepts.md#concept-material-provider)（CMP），旨在处理[提供程序存储](DDBEC-legacy-concepts.md#provider-store)。它 CMPs 从提供商商店获取，并从中获取返回的加密材料。 CMPs它通常使用每个 CMP 来满足针对加密材料的多个请求。但您可以使用其提供程序存储的功能来控制材料被重复使用的程度，确定其 CMP 被轮换的频率甚至是更改它使用的 CMP 的类型而不更改最新提供程序。

**注意**  
与“最新提供程序”的 `MostRecentProvider` 符号关联的代码可能会在进程的生命周期内将加密材料存储在内存中。它可能会使调用方使用他们不再有权使用的密钥。  
`MostRecentProvider` 符号在受支持的较早版本的 DynamoDB 加密客户端中已被弃用，并已从 2.0.0 版本中移除。它被 `CachingMostRecentProvider` 符号所取代。有关更多信息，请参阅 [最新提供程序的更新](#mrp-versions)。

对于需要最大程度地减少对提供程序存储及其加密源的调用的应用程序，以及能够在不违反应用程序的安全性要求的情况下重复使用某些加密材料的应用程序，最新提供程序是一个很好的选择。例如，它允许您在 in [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS) 下保护您的加密材料，而无需[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)在 AWS KMS 每次加密或解密项目时都调用。

您选择的提供商存储决定了最新提供程序使用的类型以及它获得新 CMP 的频率。 CMPs 您可以将任何兼容的提供程序存储与最新提供程序结合使用，包括您设计的自定义提供程序存储。

DynamoDB 加密客户端包括*MetaStore*一个用于创建和[返回包装材料提供者（已包装](wrapped-provider.md)）的。 CMPs将其生成的 Wrap CMPs ped 的多个版本 MetaStore 保存在内部 DynamoDB 表中，并通过 DynamoDB 加密客户端的内部实例使用客户端加密对其进行保护。

您可以将配置 MetaStore 为使用任何类型的内部 CMP 来保护表中的材料，包括生成受您保护的加密材料的 Di [rect KMS 提供程序](direct-kms-provider.md) AWS KMS key、使用您提供的封装和签名密钥的 Wrapped CMP，或者您设计的兼容自定义 CMP。

**有关示例代码，请参阅：**
+ 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**
+ [使用方法](#mrp-how-to-use-it)
+ [工作原理](#mrp-how-it-works)
+ [最新提供程序的更新](#mrp-versions)

## 使用方法
<a name="mrp-how-to-use-it"></a>

要创建最新提供程序，您需要创建和配置一个提供程序存储，然后创建使用该提供程序存储的最新提供程序。

[以下示例说明如何创建使用的最新提供程序， MetaStore 并使用直接 KMS 提供程序提供的加密材料保护其内部 DynamoDB 表中的版本。](direct-kms-provider.md)这些示例使用 [`CachingMostRecentProvider`](#mrp-versions) 符号。

每个最新提供程序都有一个用于在 MetaStore 表 CMPs 中标识其名称的名称、一个 [time-to-live](#most-recent-provider-ttl)(TTL) 设置和一个决定缓存可以容纳多少条目的缓存大小设置。这些示例将缓存大小设置为 1000 个条目，并将 TTL 设置为 60 秒。

------
#### [ 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
)
```

------

## 工作原理
<a name="mrp-how-it-works"></a>

最新提供商 CMPs 来自提供商商店。然后，它使用 CMP 生成由它返回到项目加密程序的加密材料。

### 关于最新提供程序
<a name="about-mrp"></a>

最新提供程序从[提供程序存储](DDBEC-legacy-concepts.md#provider-store)中获得[加密材料提供程序](DDBEC-legacy-concepts.md#concept-material-provider)（CMP）。然后，它使用 CMP 生成由它返回的加密材料。每个最新提供商都与一个提供商商店相关联，但一个提供商商店可以 CMPs 向多个主机上的多个提供商提供服务。

最新提供程序可与来自任何提供程序存储的任何兼容的 CMP 一起使用。它从 CMP 请求加密或解密材料，并将输出返回给项目加密程序。而不执行任何加密操作。

为了从其提供程序存储请求 CMP，最新提供程序将提供其材料名称以及要使用的现有 CMP 的版本。对于加密材料，最新提供程序始终请求最高（“最新”）版本。对于解密材料，它请求用于创建加密材料的 CMP 的版本，如下图所示。

![\[最新提供程序\]](http://docs.aws.amazon.com/zh_cn/database-encryption-sdk/latest/devguide/images/most-recent-provider-1.png)


最新提供程序将提供程序存储返回的 CMPs 版本保存在内存中的本地 “最近最少使用” (LRU) 缓存中。缓存使最新提供商能够获取所需的内容 CMPs ，而无需为每件商品调用提供商商店。您可以按需清除该缓存。

最新提供程序使用可配置的[time-to-live值](#most-recent-provider-ttl)，您可以根据应用程序的特性进行调整。

### 关于 MetaStore
<a name="about-metastore"></a>

您可以将最新提供程序与任何提供程序存储结合使用，包括兼容的自定义提供程序存储。DynamoDB 加密客户端包括 MetaStore一个安全实现，您可以对其进行配置和自定义。

A *MetaStore*是一个[提供商存储](DDBEC-legacy-concepts.md#provider-store)，用于创建并返回使用 Wr [ap CMPs](wrapped-provider.md) ped CMPs 所需的包装密钥、解包密钥和签名密钥配置的 Wrapped。对于最新提供商来说，A MetaStore 是一个安全的选项，因为 Wrapped CMPs 总是为每个项目生成唯一的项目加密密钥。只有保护项目加密密钥和签名密钥的包装密钥才会被重用。

下图显示了的组件 MetaStore 及其与最新提供程序的交互方式。

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


 MetaStore 生成 Wrapped CMPs，然后将它们（以加密形式）存储在内部 DynamoDB 表中。分区键是最新提供程序材料的名称；排序键则是其版本号。该表中的材料由内部 DynamoDB 加密客户端保护，包括一个项目加密程序和内部[加密材料提供程序](DDBEC-legacy-concepts.md#concept-material-provider)（CMP）。

您可以在中使用任何类型的内部 CMP MetaStore，包括[直接 KMS 提供程序](wrapped-provider.md)、包含您提供的加密材料的 Wrapped CMP 或兼容的自定义 CMP。如果您的内部 CMP MetaStore 是直接 KMS 提供商，则您的可重复使用的封装和签名密钥将受到 [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) 的保护。 AWS KMS 每次向其内部表添加新的 CMP 版本或从其内部表中获取 CMP 版本时，都会 MetaStore 调用。

### 设置一个 time-to-live值
<a name="most-recent-provider-ttl"></a>

您可以为创建的每个最新提供程序设置一个 time-to-live (TTL) 值。通常情况下，请在您的应用程序中使用实用的最低 TTL 值。

最新提供程序的 `CachingMostRecentProvider` 符号中的 TTL 值的使用已更改。

**注意**  
最新提供程序的 `MostRecentProvider` 符号在受支持的较早版本的 DynamoDB 加密客户端中已被弃用，并已从 2.0.0 版本中移除。它被 `CachingMostRecentProvider` 符号所取代。建议您尽快更新代码。有关更多信息，请参阅 [最新提供程序的更新](#mrp-versions)。

**`CachingMostRecentProvider`**  
`CachingMostRecentProvider` 以两种不同的方式使用 TTL 值。  
+ TTL 决定了最新提供程序在提供程序存储中检查新版本的 CMP 的频率。如果有新版本可用，最新提供程序将会替换其 CMP 并刷新其加密材料。否则，它将继续使用它的当前 CMP 和加密材料。
+ TTL 决定了可以在缓存 CMPs 中使用多长时间。在使用缓存的 CMP 进行加密之前，最新提供程序会评估其在缓存中存在的时间。如果 CMP 缓存时间超过 TTL，则 CMP 将从缓存中被驱逐，最新提供程序将从其提供程序存储中获取最新版本的新 CMP。

**`MostRecentProvider`**  
在 `MostRecentProvider` 中，TTL 决定了最新提供程序在提供程序存储中检查新版本的 CMP 的频率。如果有新版本可用，最新提供程序将会替换其 CMP 并刷新其加密材料。否则，它将继续使用它的当前 CMP 和加密材料。

TTL 并不能确定新的 CMP 版本的创建频率。您可以通过[轮换加密材料](#most-recent-provider-rotate)来创建新的 CMP 版本。

理想的 TTL 值将因应用程序及其延迟和可用性目标而异。低 TTL 可缩短加密材料在内存中的存储时间，从而改善安全状况。而且，TTL 低时，会更频繁地刷新关键信息。例如，如果您的内部 CMP 是 [Direct KMS 提供程序](direct-kms-provider.md)，它会更频繁地验证调用方是否仍有权使用 AWS KMS key。

但是，如果 TTL 过短，频繁调用提供程序存储可能会增加您的成本，并导致您的提供程序存储限制来自您的应用程序和共享您的服务账户的其他应用程序的请求。通过将 TTL 与轮换加密材料的速度进行协调，可能也会让您受益。

测试期间，在不同工作负载下更改 TTL 和缓存大小，直到找到适合您的应用程序以及您的安全和性能标准的配置。

### 轮换加密材料
<a name="most-recent-provider-rotate"></a>

当最新提供程序需要加密材料时，它始终使用其所知道的最新版本的 CMP。它检查新版本的频率由您在配置最新提供程序时设置的 [time-to-live](#most-recent-provider-ttl)(TTL) 值决定。

当 TTL 到期时，最新提供程序会在提供程序存储中检查新版本的 CMP。如果有可用版本，则最新提供程序会获取它并替换其缓存中的 CMP。它将使用此 CMP 及其加密材料，直到发现提供程序存储有更新的版本。

要让提供程序存储为最新提供程序创建新版本的 CMP，请使用最新提供程序的材料名称调用提供程序存储的“创建新提供程序”操作。提供程序存储将创建一个新 CMP 并在其内部存储中以更高的版本号保存加密复本。（它还将返回 CMP，但您可以丢弃它。） 因此，下次最新提供程序向提供程序商店查询其最大版本号时 CMPs，它会获得新的更大版本号，并在随后向存储请求时使用该版本号来查看是否创建了新版本的 CMP。

您可以基于时间、已处理的项目或属性数或者对您的应用程序有意义的其他指标计划您的“创建新提供程序”调用。

### 获取加密材料
<a name="most-recent-provider-encrypt"></a>

最新提供程序使用以下过程（如图所示）来获取它返回到项目加密程序的加密材料。输出取决于提供程序存储返回的 CMP 的类型。最新提供程序可以使用任何兼容的提供程序存储，包括 DynamoDB 加密客户端中包含的。 MetaStore 

![\[DynamoDB 加密客户端中最新提供程序的输入、处理和输出\]](http://docs.aws.amazon.com/zh_cn/database-encryption-sdk/latest/devguide/images/most-recent-provider-provider-store.png)


使用[`CachingMostRecentProvider`符号](#mrp-versions)创建最新提供程序时，需要指定提供程序存储区、最新提供程序的名称和 [time-to-live](#most-recent-provider-ttl)(TTL) 值。您也可以选择指定缓存大小，该大小决定缓存中可以存在的最大加密材料数量。

当项目加密程序向最新提供程序请求加密材料时，最新提供程序首先会在其缓存中搜索其 CMP 的最新版本。
+ 如果它在缓存中找到了最新版本的 CMP 且 CMP 没有超出 TTL 值，则最新提供程序将使用 CMP 来生成加密材料。然后，它将加密材料返回到项目加密程序。此操作不需要调用提供程序存储。
+ 如果最新版本的 CMP 不在其缓存中，或者如果它在缓存中但已超出其 TTL 值，则最新提供程序将从其提供程序存储请求 CMP。该请求包含最新提供程序材料名称以及它知道的最高版本号。

  1. 提供程序存储从其持久性存储返回 CMP。如果提供程序存储是 MetaStore，则使用最新提供程序材料名称作为分区键，使用版本号作为排序键，从其内部 DynamoDB 表中获取加密的 Wrapped CMP。 MetaStore 使用其内部项目加密器和内部 CMP 来解密 Wrapped CMP。然后，它将明文 CMP 返回到最新提供程序。如果内部 CMP 是 [Direct KMS 提供程序](direct-kms-provider.md)，此步骤将包含对 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) 的调用。

  1. CMP 将 `amzn-ddb-meta-id` 域添加到[实际材料描述](DDBEC-legacy-concepts.md#legacy-material-description)。该域的值是 CMP 在其内部表中的材料名称和版本。提供程序存储将 CMP 返回到最新提供程序。

  1. 最新提供程序在内存中缓存 CMP。

  1. 最新提供程序使用 CMP 生成加密材料。然后，它将加密材料返回到项目加密程序。

### 获取解密材料
<a name="most-recent-provider-decrypt"></a>

当项目加密程序向最新提供程序请求解密材料时，最新提供程序将使用以下过程来获取并返回这些材料。

1. 最新提供程序向提供程序存储询问用于加密项目的加密材料的版本号。提供程序存储传入来自项目的[材料描述属性](DDBEC-legacy-concepts.md#legacy-material-description)的实际材料描述。

1. 提供程序存储从实际材料描述中的 `amzn-ddb-meta-id` 域获取加密 CMP 版本号并将其返回到最新提供程序。

1. 最新提供程序在缓存中搜索用于加密和签署项目的 CMP 版本。
+ 如果发现缓存中存在匹配版本的 CMP，并且 CMP 未超过 [time-to-live (TTL) 值](#most-recent-provider-ttl)，则最新提供程序会使用 CMP 生成解密材料。然后，它将解密材料返回到项目加密程序。此操作不需要调用提供程序存储或任何其他 CMP。
+ 如果匹配版本的 CMP 不在其缓存中，或者如果缓存的 AWS KMS key 已超出其 TTL 值，则最新提供程序将从其提供程序存储请求 CMP。它将在请求中发送其材料名称和加密 CMP 版本号。

  1. 提供程序存储将最新提供程序名称用作分区键并将版本号用作排序键，以便在其持久性存储中搜索 CMP。
     + 如果名称和版本号不在其持久性存储中，提供程序存储将引发异常。如果提供程序存储用于生成 CMP，那么 CMP 应该存储在其持久性存储中，除非它被意外删除。
     + 如果具有匹配的名称和版本号的 CMP 位于提供程序存储的持久性存储中，提供程序存储会将指定 CMP 返回到最新提供程序。

       如果提供商存储是 MetaStore，则它会从其 DynamoDB 表中获取加密的 CMP。然后，它从其内部 CMP 获取加密材料以解密已加密的 CMP，再将 CMP 返回到最新提供程序。如果内部 CMP 是 [Direct KMS 提供程序](direct-kms-provider.md)，此步骤将包含对 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) 的调用。

  1. 最新提供程序在内存中缓存 CMP。

  1. 最新提供程序使用 CMP 生成解密材料。然后，它将解密材料返回到项目加密程序。

## 最新提供程序的更新
<a name="mrp-versions"></a>

最新提供程序的符号已从 `MostRecentProvider` 更改为 `CachingMostRecentProvider`。

**注意**  
`MostRecentProvider` 符号代表最新提供程序，在适用于 Java 的 DynamoDB 加密客户端 1.15 版本和适用于 Python 的 DynamoDB 加密客户端 1.3 版本中已被弃用，并已从两种语言实现的 DynamoDB 加密客户端 2.0.0 版本中移除。可改用 `CachingMostRecentProvider`。

`CachingMostRecentProvider` 实现了以下更改：
+ 当加密材料在内存中的时间超过配置的 [time-to-live (TTL)](#most-recent-provider-ttl) 值时，会`CachingMostRecentProvider`定期将其从内存中删除。

  `MostRecentProvider` 可能会在进程的整个生命周期内将加密材料存储在内存中。因此，最新提供程序可能不知道授权更改。它可能会在调用方使用加密密钥的权限被撤消后使用它们。

  如果您无法更新到此新版本，则可以通过定期在缓存上调用 `clear()` 方法来获得类似的效果。此方法将手动刷新缓存内容，并要求最新提供程序请求新的 CMP 和新的加密材料。
+ `CachingMostRecentProvider` 还包括缓存大小设置，该设置可让您更好地控制缓存。

要更新到 `CachingMostRecentProvider`，您必须更改代码中的符号名称。在所有其他方面，`CachingMostRecentProvider` 完全向后兼容 `MostRecentProvider`。您无需重新加密任何表项目。

但是，`CachingMostRecentProvider` 会生成更多对底层密钥基础设施的调用。它在每个 time-to-live (TTL) 间隔中至少调用一次提供商存储区。具有大量活动状态 CMPs （由于频繁轮换）的应用程序或具有大型队列的应用程序最有可能对这种变化很敏感。

在发布更新后的代码之前，请对其进行全面测试，确保更频繁的调用不会损害您的应用程序或导致提供商所依赖的服务（例如 AWS Key Management Service (AWS KMS) 或 Amazon DynamoDB）的限制。要缓解任何性能问题，请`CachingMostRecentProvider`根据您观察到 time-to-live的性能特征调整缓存大小和缓存的大小。有关指南，请参阅[设置一个 time-to-live值](#most-recent-provider-ttl)。