

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 最近提供者
<a name="most-recent-provider"></a>

**注意**  
我們的用戶端加密程式庫已[重新命名為 AWS 資料庫加密 SDK](DDBEC-rename.md)。下列主題提供有關適用於 Java 的 DynamoDB 加密用戶端 1.*x*-2.*x* 版和適用於 Python 的 DynamoDB 加密用戶端 1.*x*-3.*x* 版的資訊。如需詳細資訊，請參閱[AWS 資料庫加密 SDK for DynamoDB 版本支援](legacy-dynamodb-encryption-client.md#legacy-support)。

*最近提供者*是一個[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)，旨在與[提供者存放區](DDBEC-legacy-concepts.md#provider-store)搭配使用。它會從提供者存放區取得 CMP，並取得它從 CMP 傳回的密碼編譯資料。其通常會使用各個 CMP 因應多次密碼編譯資料請求。但您也可以使用提供者存放區的功能來控制資料的重複使用程度、決定 CMP 的輪換頻率，甚至在不變更「最近提供者」的情況下變更所使用的 CMP 類型。

**注意**  
與最近提供者的 `MostRecentProvider`符號相關聯的程式碼可能會在程序的生命週期內將密碼編譯資料存放在記憶體中。它可能會允許發起人使用他們不再獲授權使用的金鑰。  
`MostRecentProvider` 符號已在 DynamoDB 加密用戶端的較舊支援版本中棄用，並從 2.0.0 版中移除。它被 `CachingMostRecentProvider`符號取代。如需詳細資訊，請參閱[最近提供者的更新](#mrp-versions)。

對於需要盡可能避免呼叫提供者存放區與其密碼編譯來源的應用程式，以及可重複使用部分密碼編譯資料而不會違反安全性需求的應用程式，最近提供者將是理想的選擇。例如，它可讓您在 [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 類型，以及其取得新 CMP 的頻率。您可以使用任何相容提供者存放區搭配最近提供者，包括您所設計的自訂提供者存放區。

DynamoDB 加密用戶端包含 *MetaStore*，可建立和傳回[包裝材料提供者 ](wrapped-provider.md)（包裝 CMPs)。MetaStore 會儲存其在內部 DynamoDB 資料表中產生的多個包裝 CMPs 版本，並透過 DynamoDB 加密用戶端的內部執行個體進行用戶端加密來保護它們。

您可以設定 MetaStore 使用任何類型的內部 CMP 來保護資料表中的資料，包括產生受 保護之密碼編譯資料的[直接 KMS 提供者](direct-kms-provider.md) AWS KMS key、使用您提供的包裝和簽署金鑰的包裝 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 提供者](direct-kms-provider.md)的密碼編譯資料來保護其內部 DynamoDB 資料表中的版本。這些範例使用 [`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>

最近提供者會從提供者存放區取得 CMP。然後，它會使用 CMP 來產生密碼編譯資料並將其傳回給項目加密程式。

### 關於最近提供者
<a name="about-mrp"></a>

最近的提供者會從提供者[存放區](DDBEC-legacy-concepts.md#provider-store)取得[密碼編譯資料](DDBEC-legacy-concepts.md#concept-material-provider)提供者 (CMP)。然後，它會使用 CMP 來產生可傳回的密碼編譯資料。每個最近提供者都會與一個提供者存放區相關聯，但提供者存放區可以將 CMP 提供給多部主機上的多個提供者。

最近提供者可與任何提供者存放區中的任何相容 CMP 搭配使用。它會向 CMP 請求加密或解密資料，並將輸出傳回給項目加密程式。並不會執行任何密碼編譯操作。

若要向提供者存取區請求 CMP，最近提供者可提供其資料名稱以及想要使用的現有 CMP 版本。針對加密資料，最近提供者一律會請求最大 (「最近」) 版本。針對解密資料，其將請求用來建立加密資料的 CMP 版本 (如下圖所示)。

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


最近提供者會將提供者存放區傳回的 CMP 版本儲存於記憶體中的本機最久未使用 (LRU) 快取。此快取可讓最近提供者取得它所需的 CMP，而不需針對每個項目呼叫提供者存放區。您可以隨需清除此快取。

最近的提供者使用可設定的[time-to-live值](#most-recent-provider-ttl)，您可以根據應用程式的特性進行調整。

### 關於中繼存放區
<a name="about-metastore"></a>

您可以使用最近提供者搭配任何提供者存放區，包括相容的自訂提供者存放區。DynamoDB 加密用戶端包含 MetaStore，這是您可以設定和自訂的安全實作。

*中繼存放區*是一個[提供者存放區](DDBEC-legacy-concepts.md#provider-store)，可建立及傳回包裝 CMP 所需的包裝金鑰、取消包裝金鑰和簽署金鑰設定的[包裝 CMP](wrapped-provider.md)。MetaStore 是最近提供者的安全選項，因為包裝 CMPs一律為每個項目產生唯一的項目加密金鑰。只有可保護項目加密金鑰的包裝金鑰以及簽署金鑰能重複使用。

下圖說明中繼存放區元件以及其與最近提供者互動的方式。

![\[中繼存放區\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/most-recent-provider-2.png)


MetaStore 會產生包裝 CMPs，然後將它們 （以加密形式） 存放在內部 DynamoDB 資料表中。分割區索引鍵是最近提供者材料的名稱；排序索引鍵是其版本編號。資料表中的資料受到內部 DynamoDB 加密用戶端的保護，包括項目加密程式和內部[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)。

您可在中繼存放區使用任何類型的內部 CMP，包括[直接 KMS 提供者](wrapped-provider.md)、具有您所提供密碼編譯資料的包裝 CMP，或相容的自訂 CMP。如果 MetaStore 中的內部 CMP 是直接 KMS 提供者，則可重複使用的包裝和簽署金鑰會受到 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)() [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) 中的 保護AWS KMS。每次 MetaStore 將新的 CMP 版本新增至其內部資料表或從其內部資料表取得 CMP 版本 AWS KMS 時，都會呼叫 。

### 設定time-to-live值
<a name="most-recent-provider-ttl"></a>

您可以為您建立的每個最近提供者設定time-to-live(TTL) 值。一般而言，請使用適用於您應用程式的最低 TTL 值。

TTL 值的使用會在最近提供者的 `CachingMostRecentProvider`符號中變更。

**注意**  
最近提供者的`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 是[直接 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_tw/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 資料表取得加密的包裝 CMP。中繼存放區會使用其內部項目加密程式和內部 CMP，將包裝 CMP 解密。接著，它會將純文字 CMP 傳回給最近提供者。如果內部 CMP 是[直接 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 是[直接 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)。