

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

# 密碼編譯資料提供者
<a name="crypto-materials-providers"></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)。

使用 DynamoDB 加密用戶端時，您所做的最重要決策之一是選取[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)。CMP 會整合密碼編譯資料，並將其傳回至項目加密程式。它也會決定加密和簽署金鑰的產生方式、要為每個項目產生新的金鑰資料還是重複使用這些資料，以及所使用的加密和簽署演算法等。

您可以從 DynamoDB Encryption Client 程式庫中提供的實作中選擇 CMP，或建置相容的自訂 CMP。您的 CMP 選擇也可能取決於您所使用的[程式設計語言](programming-languages.md)。

本主題說明最常見的 CMP，並提供相關建議以協助您選擇最適用於應用程式的 CMP。

**直接 KMS 資料提供者**  
Direct KMS 資料提供者會在 下保護您的資料表項目[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)，這些項目絕不會讓 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS) 處於未加密狀態。您的應用程式不會產生或管理任何密碼編譯資料。由於它使用 AWS KMS key 為每個項目產生唯一的加密和簽署金鑰，因此每次加密或解密項目時，此提供者 AWS KMS 都會呼叫 。  
如果您使用 AWS KMS ，而且每筆交易一個 AWS KMS 呼叫對您的應用程式來說是可行的，則此供應商是不錯的選擇。  
如需詳細資訊，請參閱[直接 KMS 資料提供者](direct-kms-provider.md)。

**包裝資料提供者 (包裝 CMP)**  
包裝資料提供者 （包裝 CMP) 可讓您在 DynamoDB 加密用戶端外部產生和管理包裝和簽署金鑰。  
包裝 CMP 會為每個項目產生唯一的加密金鑰。接著，它會使用您所提供的包裝 (或取消包裝) 和簽署金鑰。如此，您可決定包裝和簽署金鑰的產生方式，以及要讓每個項目各有唯一的金鑰還是重複使用這些金鑰。包裝 CMP 是[直接 KMS 提供者](direct-kms-provider.md)的安全替代方案，適用於不使用 AWS KMS 且可以安全管理密碼編譯資料的應用程式。  
如需詳細資訊，請參閱[包裝資料提供者](wrapped-provider.md)。

**最近提供者**  
*最近提供者*是一個[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)，旨在與[提供者存放區](DDBEC-legacy-concepts.md#provider-store)搭配使用。它會從提供者存放區取得 CMP，並取得它從 CMP 傳回的密碼編譯資料。最近提供者通常會使用各個 CMP 因應多次密碼編譯資料請求，但您也可以使用提供者存放區的功能來控制資料重複使用的程度、決定輪換 CMP 的頻率，甚至在不變更最近提供者的情況下變更所使用的 CMP 類型。  
您可以將最近提供者與任何相容的提供者存放區搭配使用。DynamoDB 加密用戶端包含 MetaStore，這是傳回包裝 CMPs的提供者存放區。  
對於需要盡可能避免呼叫其密碼編譯來源的應用程式，以及可重複使用部分密碼編譯資料而不會違反安全性需求的應用程式，最近提供者將是理想的選擇。例如，它可讓您在 [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 在每次加密或解密項目時呼叫 。  
如需詳細資訊，請參閱[最近提供者](most-recent-provider.md)。

**靜態資料提供者**  
靜態資料提供者是針對測試、概念驗證示範和舊版相容性而設計的。它不會為每個項目產生任何唯一的密碼編譯資料。它會傳回您所提供的相同加密和簽署金鑰，並直接使用這些金鑰來加密、解密和簽署您的資料表項目。  
Java 程式庫中的[非對稱靜態提供者](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)不是靜態提供者。其僅提供[包裝 CMP](wrapped-provider.md) 的替代建構函數。此提供者可在生產環境中安全地使用，但只要情況允許，您即應直接使用包裝 CMP。

**Topics**
+ [直接 KMS 資料提供者](direct-kms-provider.md)
+ [包裝資料提供者](wrapped-provider.md)
+ [最近提供者](most-recent-provider.md)
+ [靜態資料提供者](static-provider.md)

# 直接 KMS 資料提供者
<a name="direct-kms-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)。

*Direct KMS 資料提供者* (Direct KMS 提供者） 可在 下保護您的資料表項目[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)，這些項目絕不會讓 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS) 處於未加密狀態。此[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider)會為每個資料表項目傳回唯一的加密金鑰和簽署金鑰。若要這樣做，它會 AWS KMS 在每次加密或解密項目時呼叫 。

如果您以高頻率和大規模處理 DynamoDB 項目，可能會超過 AWS KMS [requests-per-second數限制](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second)，導致處理延遲。如果您需要超過限制，請在 [AWS 支援 中心](https://console.aws.amazon.com/support/home)建立案例。您也可以考慮使用金鑰重複使用受限的密碼編譯資料提供者，例如[最近提供者](most-recent-provider.md)。

若要使用直接 KMS 提供者，發起人必須擁有 [AWS 帳戶](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)、至少一個 AWS KMS key和 許可，才能在 上呼叫 [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 和 [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 操作 AWS KMS key。 AWS KMS key 必須是對稱加密金鑰；DynamoDB 加密用戶端不支援非對稱加密。如果您使用的是 [DynamoDB 全域資料表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)，建議您指定[AWS KMS 多區域金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)。如需詳細資訊，請參閱[使用方式](#provider-kms-how-to-use)。

**注意**  
當您使用直接 KMS 提供者時，主要金鑰屬性的名稱和值會以純文字顯示在相關 AWS KMS 操作的[AWS KMS 加密內容](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)和 AWS CloudTrail 日誌中。不過，DynamoDB 加密用戶端永遠不會公開任何加密屬性值的純文字。

Direct KMS 提供者是 DynamoDB Encryption Client 支援的數個[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) 之一。如需其他 CMP 的相關資訊，請參閱[密碼編譯資料提供者](crypto-materials-providers.md)。

**如需範例程式碼，請參閱：**
+ 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**
+ [使用方式](#provider-kms-how-to-use)
+ [運作方式](#provider-kms-how-it-works)

## 使用方式
<a name="provider-kms-how-to-use"></a>

若要建立直接 KMS 提供者，請使用金鑰 ID 參數在您的帳戶中指定對稱加密 [KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)。金鑰 ID 參數的值可以是 的金鑰 ID、金鑰 ARN、別名名稱或別名 ARN AWS KMS key。如需金鑰識別符的詳細資訊，請參閱《 *AWS Key Management Service 開發人員指南*》中的[金鑰識別符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。

Direct KMS 提供者需要對稱加密 KMS 金鑰。無法使用非對稱 KMS 金鑰。不過，您可以使用多區域 KMS 金鑰、具有匯入金鑰材料的 KMS 金鑰，或自訂金鑰存放區中的 KMS 金鑰。您必須擁有 KMS 金鑰的 [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 和 [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 許可。因此，您必須使用客戶受管金鑰，而非 AWS 受管或 AWS 擁有的 KMS 金鑰。

適用於 Python 的 DynamoDB 加密用戶端會在金鑰 ID 參數值中，決定要 AWS KMS 從 區域呼叫的區域，如果包含一個。否則，如果您在 AWS KMS 用戶端中指定一個 或您在 中設定的 區域，它會使用 區域 適用於 Python (Boto3) 的 AWS SDK。如需 Python 中區域選擇的資訊，請參閱《適用於 Python (Boto3) 的 AWS SDK API 參考》中的[組態](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)。

如果您指定的用戶端包含區域，則適用於 Java 的 DynamoDB 加密用戶端會決定 AWS KMS 從用戶端中的 AWS KMS 區域呼叫的區域。否則，它會使用您在 中設定的 區域 適用於 Java 的 AWS SDK。如需 中區域選擇的相關資訊 適用於 Java 的 AWS SDK，請參閱《 適用於 Java 的 AWS SDK 開發人員指南》中的[AWS 區域 選擇](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html)。

------
#### [ 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 ]

下列範例使用金鑰 ARN 來指定 AWS KMS key。如果您的金鑰識別符不包含 AWS 區域，DynamoDB 加密用戶端會從設定的 Botocore 工作階段、如果有，或從 Boto 預設值取得區域。

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

------

如果您使用的是 [Amazon DynamoDB 全域資料表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)，建議您使用 AWS KMS 多區域金鑰加密資料。多區域金鑰 AWS KMS keys 不同 AWS 區域 ，可以互換使用，因為它們具有相同的金鑰 ID 和金鑰材料。如需詳細資訊，請參閱《 *AWS Key Management Service 開發人員指南*》中的[使用多區域金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)。

**注意**  
如果您使用的是全域資料表 [2017.11.29 版](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html)，則必須設定屬性動作，才不會加密或簽署預留複寫欄位。如需詳細資訊，請參閱[舊版全域資料表的問題](troubleshooting.md#fix-global-tables)。

若要搭配 DynamoDB 加密用戶端使用多區域金鑰，請建立多區域金鑰並將其複寫至應用程式執行所在的區域。然後將直接 KMS 提供者設定為在 DynamoDB 加密用戶端呼叫的區域中使用多區域金鑰 AWS KMS。

下列範例會設定 DynamoDB 加密用戶端來加密美國東部 （維吉尼亞北部） (us-east-1) 區域中的資料，並使用多區域金鑰在美國西部 （奧勒岡） (us-west-2) 區域中解密資料。

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

在此範例中，DynamoDB 加密用戶端 AWS KMS 會從 AWS KMS 用戶端中的 區域取得要呼叫的 區域。此`keyArn`值可識別相同區域中的多區域金鑰。

```
// 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 ]

在此範例中，DynamoDB 加密用戶端 AWS KMS 會從金鑰 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)
```

------

## 運作方式
<a name="provider-kms-how-it-works"></a>

Direct KMS 提供者會傳回受 AWS KMS key 您指定 保護的加密和簽署金鑰，如下圖所示。

![\[DynamoDB 加密用戶端中直接 KMS 提供者的輸入、處理和輸出\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/directKMS.png)

+ 若要產生加密資料，直接 KMS 提供者 AWS KMS 會要求 使用您指定的 AWS KMS key 為每個項目[產生唯一的資料金鑰](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)。它會從[資料金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)的純文字複本衍生項目的加密和簽署金鑰，然後傳回加密和簽署金鑰，以及在項目[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description)中存放的加密資料金鑰。

  項目加密程式會在使用加密和簽署金鑰後，盡快將其從記憶體中移除。加密的項目中只會儲存用來衍生這些金鑰的資料金鑰加密複本。
+ 若要產生解密資料，直接 KMS 提供者 AWS KMS 會要求 解密加密的資料金鑰。隨後，它會從純文字資料金鑰衍生驗證和簽署金鑰，並將它們傳回至項目加密程式。

  項目加密程式會驗證該項目，如果驗證成功，則會將加密的值解密。接著，它會盡快從記憶體中移除這些金鑰。

### 取得加密資料
<a name="direct-kms-get-encryption-materials"></a>

本節將詳細說明直接 KMS 提供者在接收到來自[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)的加密資料請求時的輸入、輸出和處理情形。

**輸入** (從應用程式)
+ 的金鑰 ID AWS KMS key。

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context)

**輸出** (到項目加密程式)
+ 加密金鑰 (純文字)
+ 簽署金鑰
+ 在[實際資料描述](DDBEC-legacy-concepts.md#legacy-material-description)中：這些值會儲存在用戶端新增至項目的資料描述屬性中。
  + amzn-ddb-env-key：由 加密的 Base64-encoded資料金鑰 AWS KMS key
  + amzn-ddb-env-alg：加密演算法，預設為 [AES/256](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/archived-crypto-projects/aes-development)
  + amzn-ddb-sig-alg：簽署演算法，預設為 [HmacSHA256/256](https://en.wikipedia.org/wiki/HMAC)
  + amzn-ddb-wrap-alg：kms

**處理**

1. Direct KMS 提供者會傳送 AWS KMS 請求，以使用指定的 AWS KMS key 來[產生項目的唯一資料金鑰](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)。此操作會傳回以 AWS KMS key加密的純文字金鑰和複本。這項資料又稱為*初始金鑰資料*。

   此要求包含 [AWS KMS 加密內容](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)中的下列純文字值。這些非機密值會以密碼編譯的方式繫結至加密的物件，而在解密時需要相同的加密細節。您可以使用這些值來識別 [AWS CloudTrail 日誌](https://docs.aws.amazon.com/kms/latest/developerguide/monitoring-overview.html) AWS KMS 中的 呼叫。
   + amzn-ddb-env-alg – 預設 AES/256 加密演算法
   + amzn-ddb-sig-alg – 簽署演算法，預設 HmacSHA256/256
   + （選用） aws-kms-table – *資料表名稱*
   + （選用） *分割區索引鍵名稱* – *分割區索引鍵值* （二進位值為 Base64-encoded)
   + （選用） *排序索引鍵名稱* – *排序索引鍵值* （二進位值為 Base64-encoded)

   Direct KMS 提供者會從項目的 DynamoDB AWS KMS 加密內容取得加密內容的值。 [DynamoDB ](concepts.md#encryption-context) 如果 DynamoDB 加密內容不包含值，例如資料表名稱，則會從 AWS KMS 加密內容中省略該名稱值對。

1. 直接 KMS 提供者會從資料金鑰衍生對稱加密金鑰和簽署金鑰。根據預設，其將使用[安全雜湊演算法 (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) 和 [RFC5869 HMAC 式金鑰衍生函數](https://tools.ietf.org/html/rfc5869)，衍生 256 位元 AES 對稱加密金鑰和 256 位元 HMAC-SHA-256 簽署金鑰。

1. 直接 KMS 提供者會將輸出傳回至項目加密程式。

1. 項目加密程式會採用實際資料描述中指定的演算法，使用加密金鑰為指定的屬性加密，並使用簽署金鑰加以簽署。它會盡快從記憶體中移除這些純文字金鑰。

### 取得解密資料
<a name="direct-kms-get-decryption-materials"></a>

本節將詳細說明直接 KMS 提供者在接收到來自[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)的解密資料請求時的輸入、輸出和處理情形。

**輸入** (從應用程式)
+ 的金鑰 ID AWS KMS key。

  金鑰 ID 的值可以是 的金鑰 ID、金鑰 ARN、別名名稱或別名 ARN AWS KMS key。未包含在金鑰 ID 中的任何值，例如 區域，都必須在[AWS 具名設定檔](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)中可用。金鑰 ARN 提供所有需要的值 AWS KMS 。

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context)的副本，其中包含材料描述屬性的內容。

**輸出** (到項目加密程式)
+ 加密金鑰 (純文字)
+ 簽署金鑰

**處理**

1. Direct KMS 提供者會從加密項目中的資料描述屬性取得加密的資料金鑰。

1. 它會要求 AWS KMS 使用指定的 AWS KMS key 來[解密](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)加密的資料金鑰。此操作會傳回純文字金鑰。

   此要求必須使用先前用來產生和加密資料金鑰的相同 [AWS KMS 加密內容](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)。
   + aws-kms-table – *資料表名稱*
   + *分割區索引鍵名稱* – *分割區索引鍵值* （二進位值為 Base64-encoded)
   + （選用） *排序索引鍵名稱* – *排序索引鍵值* （二進位值為 Base64-encoded)
   + amzn-ddb-env-alg – 預設 AES/256 加密演算法
   + amzn-ddb-sig-alg – 簽署演算法，預設 HmacSHA256/256

1. 直接 KMS 提供者會使用[安全雜湊演算法 (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) 和 [RFC5869 HMAC 式金鑰衍生函數](https://tools.ietf.org/html/rfc5869)，從資料金鑰衍生 256 位元 AES 對稱加密金鑰和 256 位元 HMAC-SHA-256 簽署金鑰。

1. 直接 KMS 提供者會將輸出傳回至項目加密程式。

1. 項目加密程式會使用簽署金鑰來驗證項目。如果成功，則會使用對稱加密金鑰將加密的屬性值解密。這些操作會使用實際資料描述中指定的加密和簽署演算法。項目加密程式會盡快從記憶體中移除這些純文字金鑰。

# 包裝資料提供者
<a name="wrapped-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)。

*包裝資料提供者* （包裝 CMP) 可讓您將來自任何來源的包裝和簽署金鑰與 DynamoDB 加密用戶端搭配使用。包裝 CMP 不依賴於任何 AWS 服務。不過，您必須在用戶端以外產生及管理包裝和簽署金鑰，包括提供正確的金鑰來驗證和解密項目。

包裝 CMP 會為每個項目產生唯一的項目加密金鑰。其將使用您所提供的包裝金鑰來包裝項目加密金鑰，並將包裝的項目加密金鑰儲存至項目的[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description)。因為您提供包裝和簽署金鑰，所以由您決定包裝和簽署金鑰的產生方式，以及要讓每個項目各有唯一的金鑰還是重複使用。

對於可以管理密碼編譯資料的應用程式而言，包裝 CMP 是安全的實作與理想的選擇。

包裝 CMP 是 DynamoDB Encryption Client 支援的幾個[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) 之一。如需其他 CMP 的相關資訊，請參閱[密碼編譯資料提供者](crypto-materials-providers.md)。

**如需範例程式碼，請參閱：**
+ 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**
+ [使用方式](#wrapped-cmp-how-to-use)
+ [運作方式](#wrapped-cmp-how-it-works)

## 使用方式
<a name="wrapped-cmp-how-to-use"></a>

若要建立包裝 CMP，請指定包裝金鑰 (加密時需要)、取消包裝金鑰 (解密時需要) 以及簽署金鑰。您必須在加密和解密項目時提供金鑰。

包裝、取消包裝和簽署金鑰可以是對稱金鑰或非對稱金鑰對。

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

------

## 運作方式
<a name="wrapped-cmp-how-it-works"></a>

包裝 CMP 會為每個項目產生新的項目加密金鑰。如下圖所示，它會使用您所提供的包裝、取消包裝和簽署金鑰。

![\[DynamoDB 加密用戶端中包裝材料提供者的輸入、處理和輸出\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/wrappedCMP.png)


### 取得加密資料
<a name="wrapped-cmp-get-encryption-materials"></a>

本節將詳細說明包裝資料提供者 (包裝 CMP) 在接收到加密資料請求時的輸入、輸出和處理情形。

**輸入** (從應用程式)
+ 包裝金鑰：[進階加密標準](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 對稱金鑰，或 [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 公有金鑰。如有任何已加密的屬性值，則為必要。否則為選用並予以忽略。
+ 取消包裝金鑰：選用並予以忽略。
+ 簽署金鑰

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context)

**輸出** (到項目加密程式)：
+ 純文字項目加密金鑰
+ 簽署金鑰 (不變)
+ [實際資料描述](DDBEC-legacy-concepts.md#legacy-material-description)：這些值會儲存在用戶端新增至項目的[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description)中。
  + `amzn-ddb-env-key`：Base64 編碼的包裝項目加密金鑰
  + `amzn-ddb-env-alg`：用來加密項目的加密演算法。預設為 AES-256-CBC。
  + `amzn-ddb-wrap-alg`：包裝 CMP 用來包裝項目加密金鑰的包裝演算法。如果包裝金鑰是 AES 金鑰，則會使用未填補的 `AES-Keywrap` (如 [RFC 3394](https://tools.ietf.org/html/rfc3394.html) 定義) 來包裝此金鑰。如果包裝金鑰是 RSA 金鑰，則會使用 RSA OAEP (MGF1 填補) 來加密此金鑰。

**處理**

當您加密項目時，您會傳入包裝金鑰和簽署金鑰。取消包裝金鑰為選用並予以忽略。

1. 包裝 CMP 會為資料表項目產生唯一的對稱項目加密金鑰。

1. 它會使用您指定的包裝金鑰來包裝項目加密金鑰。接著，它會盡快從記憶體中移除此金鑰。

1. 其將傳回純文字項目加密金鑰、您所提供的簽署金鑰，以及包含包裝項目加密金鑰和加密與包裝演算法的[實際資料描述](DDBEC-legacy-concepts.md#legacy-material-description)。

1. 項目加密程式會使用純文字加密金鑰來加密項目。它會使用您所提供的簽署金鑰來簽署金鑰。接著，它會盡快從記憶體中移除這些純文字金鑰。它會將實際資料描述中的欄位 (包括包裝加密金鑰 (`amzn-ddb-env-key`)) 複製到項目的資料描述屬性。

### 取得解密資料
<a name="wrapped-cmp-get-decryption-materials"></a>

本節將詳細說明包裝資料提供者 (包裝 CMP) 在接收到解密資料請求時的輸入、輸出和處理情形。

**輸入** (從應用程式)
+ 包裝金鑰：選用並予以忽略。
+ 取消包裝金鑰：相同的[進階加密標準](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 對稱金鑰，或與加密使用的 [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 公有金鑰對應的 RSA 私有金鑰。如有任何已加密的屬性值，則為必要。否則為選用並予以忽略。
+ 簽署金鑰

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context)的副本，其中包含材料描述屬性的內容。

**輸出** (到項目加密程式)
+ 純文字項目加密金鑰
+ 簽署金鑰 (不變)

**處理**

當您解密項目時，您會傳入取消包裝金鑰和簽署金鑰。包裝金鑰為選用並予以忽略。

1. 包裝 CMP 會從項目的資料描述屬性取得包裝項目加密金鑰。

1. 它會使用取消包裝金鑰和演算法來取消包裝項目加密金鑰。

1. 它會將純文字項目加密金鑰、簽署金鑰以及加密和簽署演算法傳回給項目加密程式。

1. 項目加密程式會使用簽署金鑰來驗證項目。如果成功，則會使用項目加密金鑰來將項目解密。接著，它會盡快從記憶體中移除這些純文字金鑰。

# 最近提供者
<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)。

# 靜態資料提供者
<a name="static-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)。

*靜態資料提供者* (Static CMP) 是非常簡單的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)，用於測試、proof-of-concept示範和舊版相容性。

若要使用靜態 CMP 加密資料表項目，請提供[進階加密標準](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 對稱加密金鑰與簽署金鑰或金鑰對。您必須提供相同的金鑰，才能將已加密的項目解密。靜態 CMP 不會執行任何密碼編譯操作。它反而會以原狀傳遞您提供給項目加密程式的加密金鑰。項目加密程式會直接以加密金鑰加密項目。然後，直接使用簽署金鑰進行簽署。

因為靜態 CMP 不會產生任何獨特的密碼編譯資料，您處理的所有資料表項目都會使用相同加密金鑰進行加密並由相同的簽署金鑰進行簽署。當您使用相同的金鑰加密眾多項目的屬性值，或使用相同金鑰或金鑰對來簽署所有項目時，可能會超出金鑰的密碼編譯限制。

**注意**  
Java 程式庫中的[非對稱靜態提供者](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)不是靜態提供者。其僅提供[包裝 CMP](wrapped-provider.md) 的替代建構函數。此可在生產環境中安全地使用，但只要情況允許，您即應直接使用包裝 CMP。

靜態 CMP 是 DynamoDB Encryption Client 支援的數個[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMPs) 之一。如需其他 CMP 的相關資訊，請參閱[密碼編譯資料提供者](crypto-materials-providers.md)。

**如需範例程式碼，請參閱：**
+ Java：[SymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/SymmetricEncryptedItem.java)

**Topics**
+ [使用方式](#static-cmp-how-to-use)
+ [運作方式](#static-cmp-how-it-works)

## 使用方式
<a name="static-cmp-how-to-use"></a>

若要建立靜態提供者，請提供加密金鑰或金鑰對和簽署金鑰或金鑰對。您必須提供金鑰資料才能加密和解密資料表項目。

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

------

## 運作方式
<a name="static-cmp-how-it-works"></a>

靜態提供者會傳遞您提供給項目加密程式的加密和簽署金鑰，直接用來加密和簽署資料表項目。除非您針對每個項目提供不同的金鑰，否則每個項目都會使用相同金鑰。

![\[DynamoDB 加密用戶端中靜態資料提供者的輸入、處理和輸出\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/staticCMP.png)


### 取得加密資料
<a name="static-cmp-get-encryption-materials"></a>

本節將詳細說明靜態資料提供者 (靜態 CMP) 在接收到加密資料請求時的輸入、輸出和處理情形。

**輸入** (從應用程式)
+ 加密金鑰 – 這必須是對稱金鑰，例如[進階加密標準](https://tools.ietf.org/html/rfc3394.html) (AES) 金鑰。
+ 簽署金鑰 – 這可以是對稱金鑰或非對稱金鑰對。

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context)

**輸出** (到項目加密程式)
+ 當作輸入傳遞的加密金鑰。
+ 當作輸入傳遞的簽署金鑰。
+ 實際資料描述：[請求的資料描述](DDBEC-legacy-concepts.md#legacy-material-description) (如果有) 會維持原狀。

### 取得解密資料
<a name="static-cmp-get-decryption-materials"></a>

本節將詳細說明靜態資料提供者 (靜態 CMP) 在接收到解密資料請求時的輸入、輸出和處理情形。

雖然它包括取得加密資料及取得解密資料的個別方法，但是行為相同。

**輸入** (從應用程式)
+ 加密金鑰 – 這必須是對稱金鑰，例如[進階加密標準](https://tools.ietf.org/html/rfc3394.html) (AES) 金鑰。
+ 簽署金鑰 – 這可以是對稱金鑰或非對稱金鑰對。

**輸入** (從項目加密程式)
+ [DynamoDB 加密內容](concepts.md#encryption-context) （未使用）

**輸出** (到項目加密程式)
+ 當作輸入傳遞的加密金鑰。
+ 當作輸入傳遞的簽署金鑰。