

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

# 舊版 DynamoDB 加密用戶端
<a name="legacy-dynamodb-encryption-client"></a>

2023 年 6 月 9 日，我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。 AWS Database Encryption SDK 繼續支援舊版 DynamoDB Encryption Client 版本。如需使用重新命名變更之用戶端加密程式庫不同部分的詳細資訊，請參閱 [Amazon DynamoDB 加密用戶端重新命名](DDBEC-rename.md)。

若要遷移至最新版本的 DynamoDB Java 用戶端加密程式庫，請參閱 [遷移至 3.x 版](ddb-java-migrate.md)。

**Topics**
+ [AWS DynamoDB 版本的資料庫加密 SDK 支援](#legacy-support)
+ [DynamoDB 加密用戶端的運作方式](DDBEC-legacy-how-it-works.md)
+ [Amazon DynamoDB 加密用戶端概念](DDBEC-legacy-concepts.md)
+ [密碼編譯資料提供者](crypto-materials-providers.md)
+ [Amazon DynamoDB Encryption Client 可用的程式設計語言](programming-languages.md)
+ [變更您的資料模型](data-model.md)
+ [故障診斷 DynamoDB Encryption Client 應用程式的問題](troubleshooting.md)

## AWS DynamoDB 版本的資料庫加密 SDK 支援
<a name="legacy-support"></a>

舊版章節中的主題提供有關適用於 Java 的 DynamoDB 加密用戶端 1.*x*-2.*x* 版和適用於 Python 的 DynamoDB 加密用戶端 1.*x*-3.*x* 版的資訊。

下表列出支援 Amazon DynamoDB 中用戶端加密的語言和版本。


| 程式設計語言 | 版本 | SDK 主要版本生命週期階段 | 
| --- | --- | --- | 
|  Java  |  1.*x* 版  |  終止[End-of-Support階段](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)，自 2022 年 7 月起生效  | 
|  Java  |  2.*x* 版  |  [一般可用性](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 
|  Java  |  3.*x* 版  |  [一般可用性](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 
|  Python  |  1.*x* 版  |  終止[End-of-Support階段](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)，自 2022 年 7 月起生效  | 
|  Python  |  2.*x* 版  |  終止[End-of-Support階段](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)，自 2022 年 7 月起生效  | 
|  Python  |  3.*x* 版  |  [一般可用性](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 

# DynamoDB 加密用戶端的運作方式
<a name="DDBEC-legacy-how-it-works"></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 加密用戶端專為保護您存放在 DynamoDB 中的資料而設計。程式庫包括您可以擴展或以原狀使用的安全實作。再者，大多數元素是由摘要元素表示，所以您可建立和使用相容的自訂元件。

**加密並簽署資料表項目**

DynamoDB Encryption Client 的核心是一個*項目加密程式*，可加密、簽署、驗證和解密資料表項目。它會接受資料表項目相關資訊，以及要加密並簽署項目的相關指示。其將從您選取及設定的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider)取得加密資料，以及該項資料使用方式的指示。

下圖顯示此程序的高階檢視。

![\[在 DynamoDB 加密用戶端中加密和簽署項目\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/arch-encrypt.png)


若要加密和簽署資料表項目，DynamoDB 加密用戶端需要：
+ **資料表的相關資訊。 **它會從您提供的 [DynamoDB 加密內容](concepts.md#encryption-context)取得資料表的相關資訊。有些協助程式會從 DynamoDB 取得必要資訊，並為您建立 DynamoDB 加密內容。
**注意**  
*DynamoDB 加密用戶端*中的 DynamoDB 加密內容與 AWS Key Management Service (AWS KMS) 和 中的*加密內容*無關 AWS Encryption SDK。
+ **哪些屬性要加密並簽署。**其將從您提供的[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)取得這項資訊。
+ **加密資料，包括加密金鑰和簽署金鑰。**其將從您選取及設定的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) 取得這些資料。
+ **加密並簽署項目的指示**。CMP 會將可供使用加密資料 (包括加密和簽署演算法) 的指示新增至[實際資料描述](DDBEC-legacy-concepts.md#legacy-material-description)。

[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)會使用上述所有元素來加密並簽署項目。項目加密程式也會將兩個屬性新增至此項目：包含加密和簽署指示 (實際資料描述) 的[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description)，以及包含簽章的屬性。您可直接與項目加密程式互動，或使用為您與項目加密程式互動的協助程式功能來實作安全的預設行為。

結果是包含已加密並簽署之資料的 DynamoDB 項目。

**驗證並解密資料表項目**

如下圖所示，這些元件也會一起運作來驗證並解密項目。

![\[驗證和解密 DynamoDB 加密用戶端中的項目\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/arch-decrypt.png)


為了驗證和解密項目，DynamoDB 加密用戶端需要相同的元件、具有相同組態的元件，或專為解密項目而設計的元件，如下所示：
+ [DynamoDB 加密內容](concepts.md#encryption-context)中**資料表的相關資訊**。
+ **要驗證和解密哪些屬性。**其將從[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)取得這項資訊。
+ **解密資料，包括驗證和加密金鑰**，來自您選取和設定的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP)。

  已加密的項目不包含用來進行加密的 CMP 相關記錄。您必須提供相同的 CMP、具有相同組態的 CMP，或設計用來解密項目的 CMP。
+ **如何加密並簽署項目的相關資訊**，包括加密和簽署演算法。用戶端會從項目中的[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description)取得這些資訊。

[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)會使用上述所有元素來驗證並解密項目。此外，它不會移除資料描述和簽章屬性。結果是純文字 DynamoDB 項目。

# Amazon DynamoDB 加密用戶端概念
<a name="DDBEC-legacy-concepts"></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)。

本主題說明 Amazon DynamoDB 加密用戶端中使用的概念和術語。

若要了解 DynamoDB 加密用戶端的元件如何互動，請參閱 [DynamoDB 加密用戶端的運作方式](DDBEC-legacy-how-it-works.md)。

**Topics**
+ [密碼編譯資料提供者 (CMP)](#concept-material-provider)
+ [項目加密程式](#item-encryptor)
+ [屬性動作](#legacy-attribute-actions)
+ [資料描述](#legacy-material-description)
+ [DynamoDB 加密內容](#legacy-encryption-context)
+ [提供者存放區](#provider-store)

## 密碼編譯資料提供者 (CMP)
<a name="concept-material-provider"></a>

實作 DynamoDB 加密用戶端時，您的第一個任務之一是[選取密碼編譯資料提供者](crypto-materials-providers.md) (CMP) （也稱為*加密資料提供者*)。您的選擇會決定其餘的大部分實作。

*密碼編譯資料提供者* (CMP) 會收集、整合及傳回[項目加密程式](#item-encryptor)用來加密並簽署資料表項目的密碼編譯資料。CMP 會決定要使用的加密演算法，以及如何產生及保護加密和簽署金鑰。

CMP 會與項目加密程式互動。項目加密程式會請求 CMP 提供加密和解密資料，而 CMP 會將這些資料傳回給項目加密程式。然後，項目加密程式會使用密碼編譯資料將項目加密並簽署，或驗證並解密。

您會在設定用戶端時指定 CMP。您可以建立相容的自訂 CMP，或使用程式庫的其中一個 CMP。大多數 CMP 都適用於多種程式設計語言。

## 項目加密程式
<a name="item-encryptor"></a>

*項目加密程式*是執行 DynamoDB 加密用戶端密碼編譯操作的較低層級元件。其將請求[密碼編譯資料提供者](#concept-material-provider) (CMP) 提供密碼編譯資料，然後使用 CMP 傳回的資料將資料表項目加密並簽署，或驗證並解密。

您可以直接與項目加密程式互動，或使用您的程式庫所提供的協助程式。例如，適用於 Java 的 DynamoDB 加密用戶端包含可與 搭配使用的`AttributeEncryptor`協助程式類別`DynamoDBMapper`，而不是直接與`DynamoDBEncryptor`項目加密程式互動。Python 程式庫包括 `EncryptedTable`、`EncryptedClient` 和 `EncryptedResource` 協助程式類別，這些類別會替您與項目加密程式互動。

## 屬性動作
<a name="legacy-attribute-actions"></a>

*屬性動作*會告知項目加密程式要對項目的每個屬性執行什麼動作。

屬性動作值可以是下列其中一項：
+ **加密和簽署** – 加密屬性值。在項目簽章中包含屬性 (名稱和值)。
+ **僅限簽署** – 在項目簽章中包含 屬性。
+ **什麼都不做** – 請勿加密或簽署 屬性。

對於可以儲存敏感資料的任何屬性，請使用**加密並簽署**。針對主索引鍵屬性 (分割區索引鍵和排序索引鍵)，使用**僅簽署**。[資料描述屬性](#legacy-material-description)和簽章屬性不會進行簽署或加密。您不需要指定這些屬性的屬性動作。

請仔細選擇屬性動作。如有疑問，請使用**加密並簽署**。使用 DynamoDB 加密用戶端來保護資料表項目之後，您就無法在沒有簽章驗證錯誤風險的情況下變更屬性的動作。如需詳細資訊，請參閱[變更您的資料模型](data-model.md)。

**警告**  
請勿加密主索引鍵的屬性。它們必須保持純文字，以便 DynamoDB 可以在不執行完整資料表掃描的情況下找到項目。

如果 [DynamoDB 加密內容](concepts.md#encryption-context)識別您的主要金鑰屬性，當您嘗試加密它們時，用戶端會擲回錯誤。

您用來為每種程式設計語言指定屬性動作的技巧都不同。而且，該技巧可以專屬於您所使用的協助程式類別。

如需詳細資訊，請參閱程式設計語言的文件。
+ [Python](python-using.md#python-attribute-actions)
+ [Java](java-using.md#attribute-actions-java)

## 資料描述
<a name="legacy-material-description"></a>

已加密資料表項目的*資料描述*包含資料表項目加密和簽署方式的相關資訊 (例如加密演算法)。[密碼編譯資料提供者](#concept-material-provider) (CMP) 會在整合可供加密和簽署的密碼編譯資料時記錄資料描述。稍後，當它需要整合密碼編譯資料來驗證和解密項目時，它會使用資料描述作為其指南。

在 DynamoDB 加密用戶端中，材料描述是指三個相關元素：

**請求的資料描述**  
有些[密碼編譯資料提供者](#concept-material-provider) (CMP) 可讓您指定進階選項，例如加密演算法。若要指出您的選擇，請將名稱值對新增至請求中 [DynamoDB 加密內容](concepts.md#encryption-context)的資料描述屬性，以加密資料表項目。此元素又稱為*請求的資料描述*。請求的資料描述中的有效值由您所選的 CMP 定義。  
由於資料描述可能覆寫安全的預設值，除非您有充分理由要使用請求的資料描述，否則建議您將其省略。

**實際資料描述**  
[密碼編譯資料提供者](#concept-material-provider) (CMP) 傳回的資料描述又稱為*實際資料描述*。它會描述 CMP 在整合密碼編譯資料時所用的實際值。通常包含請求的資料描述及新增和變更 (如果有)。

**資料描述屬性**  
用戶端會在已加密項目的*資料描述屬性*中儲存實際資料描述。資料描述屬性名稱為 `amzn-ddb-map-desc`，而其值為實際資料描述。用戶端會使用資料描述屬性中的值來驗證並解密項目。

## DynamoDB 加密內容
<a name="legacy-encryption-context"></a>

*DynamoDB 加密內容*會將資料表和項目的相關資訊提供給[密碼編譯資料提供者](#concept-material-provider) (CMP)。在進階實作中，DynamoDB 加密內容可以包含[請求的資料描述](#legacy-material-description)。

當您加密資料表項目時，DynamoDB 加密內容會以密碼編譯方式繫結至加密的屬性值。當您解密時，如果 DynamoDB 加密內容與用來加密的 DynamoDB 加密內容不完全、區分大小寫相符，解密操作會失敗。如果您直接與[項目加密程式](#item-encryptor)互動，您必須在呼叫加密或解密方法時提供 DynamoDB 加密內容。大多數協助程式會為您建立 DynamoDB 加密內容。

**注意**  
*DynamoDB 加密用戶端*中的 DynamoDB 加密內容與 AWS Key Management Service (AWS KMS) 和 中的*加密內容*無關 AWS Encryption SDK。

DynamoDB 加密內容可包含下列欄位。所有欄位和值都是選用的。
+ 資料表名稱
+ 分割區索引鍵名稱
+ 排序索引鍵名稱
+ 屬性名稱值組
+ [請求的資料描述](#legacy-material-description)

## 提供者存放區
<a name="provider-store"></a>

*提供者存放區* 是一個可傳回[密碼編譯資料提供者](#concept-material-provider) (CMP) 的元件。提供者存放區可以建立 CMP，或從另一個來源 (例如另一個提供者存放區) 取得。提供者存放區會在持久性儲存體中儲存其建立的 CMP 版本，而存放的每個 CMP 都是依照請求者的資料名稱與版本號碼進行識別。

DynamoDB 加密用戶端中的[最近提供者](most-recent-provider.md)會從提供者存放區取得其 CMPs，但您可以使用提供者存放區將 CMPs 提供給任何元件。每個最近提供者都與一個提供者存放區相關聯，但提供者存放區可以將 CMP 提供給多部主機上的許多請求者。

提供者存放區會隨需建立新的 CMP 版本，並傳回新的和現有版本。它也會傳回特定資料名稱的最新版本號碼。這使請求者能夠得知提供者存放區何時有可請求的新版 CMP。

DynamoDB 加密用戶端包含[ MetaStore](most-recent-provider.md#about-metastore)，這是使用存放在 DynamoDB 中的金鑰建立包裝 CMPs 並使用內部 DynamoDB 加密用戶端加密的提供者存放區。

**進一步了解**：
+ 提供者存放區：[Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/ProviderStore.html)、[Python](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/src/dynamodb_encryption_sdk/material_providers/store/__init__.py)
+ 中繼存放區：[Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/MetaStore.html)、[Python](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/materials_providers/metastore.html#module-dynamodb_encryption_sdk.material_providers.store.meta)

# 密碼編譯資料提供者
<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) （未使用）

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

# Amazon DynamoDB Encryption Client 可用的程式設計語言
<a name="programming-languages"></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)。

Amazon DynamoDB 加密用戶端適用於下列程式設計語言。語言專屬的程式庫有所不同，但是產生的實作都是可互通的。例如，您可以使用 Java 用戶端來加密 (和簽署) 項目，以及使用 Python 用戶端將項目解密。

如需詳細資訊，請參閱相關主題。

**Topics**
+ [Java](java.md)
+ [Python](python.md)

# 適用於 Java 的 Amazon DynamoDB 加密用戶端
<a name="java"></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)。

本主題說明如何安裝和使用適用於 Java 的 Amazon DynamoDB 加密用戶端。如需使用 DynamoDB 加密用戶端進行程式設計的詳細資訊，請參閱 [Java 範例](java-examples.md)、GitHub 上 aws-dynamodb-encryption-java 儲存庫中[的範例](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples)，以及 DynamoDB 加密用戶端的 [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)。

**注意**  
適用於 Java 的 DynamoDB 加密用戶端版本 1.*x*.*x* 自 2022 年 7 月起處於[end-of-support階段](what-is-database-encryption-sdk.md#support)。盡快升級至較新的版本。

**Topics**
+ [先決條件](#java-prerequisites)
+ [安裝](#java-installation)
+ [使用適用於 Java 的 DynamoDB 加密用戶端](java-using.md)
+ [Java 範例](java-examples.md)

## 先決條件
<a name="java-prerequisites"></a>

安裝適用於 Java 的 Amazon DynamoDB 加密用戶端之前，請確定您有下列先決條件。

**Java 開發環境**  
您會需要 Java 8 或更新版本。在 Oracle 網站上，移至 [Java SE 下載](https://www.oracle.com/java/technologies/downloads/)，然後下載並安裝 Java SE 開發套件 (JDK)。  
如果您使用 Oracle JDK，您還必須下載並安裝 [Java Cryptography Extension (JCE) Unlimited Strength 管轄權政策檔案](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)。

**適用於 Java 的 AWS SDK**  
DynamoDB 加密用戶端需要 的 DynamoDB 模組， 適用於 Java 的 AWS SDK 即使您的應用程式未與 DynamoDB 互動。您可以安裝整個 SDK 或只安裝這個模組。如果您使用 Maven，請將 `aws-java-sdk-dynamodb` 新增到 `pom.xml` 檔案。  
如需安裝和設定 的詳細資訊 適用於 Java 的 AWS SDK，請參閱 [適用於 Java 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/getting-started.html)。

## 安裝
<a name="java-installation"></a>

您可以透過下列方式安裝適用於 Java 的 Amazon DynamoDB 加密用戶端。

**手動**  
若要安裝適用於 Java 的 Amazon DynamoDB 加密用戶端，請複製或下載 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) GitHub 儲存庫。

**使用 Apache Maven**  
Amazon DynamoDB Encryption Client for Java 可透過 [Apache Maven](https://maven.apache.org/) 使用下列相依性定義。  

```
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-dynamodb-encryption-java</artifactId>
  <version>version-number</version>
</dependency>
```

安裝軟體開發套件後，請先查看本指南中的範例程式碼，以及 GitHub 上的 [DynamoDB 加密用戶端 Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)。

# 使用適用於 Java 的 DynamoDB 加密用戶端
<a name="java-using"></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)。

本主題說明在 Java 中可能無法在其他程式設計語言實作中找到的 DynamoDB 加密用戶端的一些功能。

如需使用 DynamoDB 加密用戶端進行程式設計的詳細資訊，請參閱 [Java 範例](java-examples.md)、GitHub `aws-dynamodb-encryption-java repository`上 中[的範例](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples)，以及 DynamoDB 加密用戶端的 [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/)。



**Topics**
+ [項目加密程式](#attribute-encryptor)
+ [設定儲存行為](#save-behavior)
+ [Java 中的屬性動作](#attribute-actions-java)
+ [覆寫表格名稱](#override-table-name)

## 項目加密程式：AttributeEncryptor 和 DynamoDBEncryptor
<a name="attribute-encryptor"></a>

Java 中的 DynamoDB 加密用戶端有兩個[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)：較低層級的 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) 和 [AttributeEncryptor](#attribute-encryptor)。

`AttributeEncryptor` 是一種協助程式類別，可協助您在 DynamoDB 加密用戶端的 中使用 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html) 適用於 Java 的 AWS SDK 與 。 `DynamoDB Encryptor` DynamoDB 當您搭配 `DynamoDBMapper` 使用 `AttributeEncryptor` 時，它會在您保存項目時，透明地加密和簽署您的項目。當您載入項目時，它也會透明地驗證和解密您的項目。

## 設定儲存行為
<a name="save-behavior"></a>

您可以使用 `AttributeEncryptor`和 `DynamoDBMapper` ，將資料表項目新增或取代為僅簽署或加密和簽署的屬性。對於這些任務，我們建議您將其設定為使用 `PUT` 儲存行為，如下列範例所示。否則，您將可能無法解密資料。

```
DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
```

如果您使用預設儲存行為，只會更新在資料表項目中建模的屬性，則未建模的屬性不會包含在簽章中，也不會透過資料表寫入變更。因此，在稍後讀取所有屬性時，簽章將不會驗證，因為它不包含未建模的屬性。

您也可以使用 `CLOBBER` 儲存行為。這種行為與 `PUT` 儲存行為完全相同，差別在於它會停用樂觀鎖定並覆寫表格中的項目。

為了防止簽章錯誤，如果 `AttributeEncryptor` 與未設定為 `CLOBBER`或 的儲存行為`DynamoDBMapper`的 搭配使用，則 DynamoDB Encryption Client 會擲回執行期例外狀況`PUT`。

若要查看範例中使用的此程式碼，請參閱 [使用 DynamoDBMapper](java-examples.md#java-example-dynamodb-mapper)和 GitHub 中`aws-dynamodb-encryption-java`儲存庫中的 [AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java) 範例。

## Java 中的屬性動作
<a name="attribute-actions-java"></a>

[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)決定哪些屬性值會加密並簽署，哪些屬性值只會簽署，以及哪些屬性值會予忽略。您用來指定屬性動作的方法取決於您使用的是 `DynamoDBMapper` 和 `AttributeEncryptor`，還是較低層層級的 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html)。

**重要**  
使用屬性動作加密表格項目後，從資料模型新增或移除屬性可能會導致簽章驗證錯誤，讓您無法解密資料。如需更詳細的說明，請參閱[變更您的資料模型](data-model.md)。

### DynamoDBMapper 的屬性動作
<a name="attribute-action-java-mapper"></a>

當您使用 `DynamoDBMapper` 和 `AttributeEncryptor` 時，您可使用註釋來指定屬性動作。DynamoDB 加密用戶端使用[標準 DynamoDB 屬性註釋](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Annotations.html)來定義屬性類型，以判斷如何保護屬性。除了主要索引鍵 (簽署但不加密) 以外，所有屬性都預設會進行加密和簽署。

**注意**  
雖然您可以 (而且應該) 簽署屬性值，但請勿使用 [@DynamoDBVersionAttribute 註釋](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)來加密屬性值。否則，使用其值的情況將會造成想不到的影響。

```
// Attributes are encrypted and signed
@DynamoDBAttribute(attributeName="Description")

// Partition keys are signed but not encrypted
@DynamoDBHashKey(attributeName="Title")

// Sort keys are signed but not encrypted
@DynamoDBRangeKey(attributeName="Author")
```

若要指定例外狀況，請使用 DynamoDB Encryption Client for Java 中定義的加密註釋。如果您在類別層級指定例外狀況，這些例外狀況就會成為類別的預設值。

```
// Sign only
@DoNotEncrypt

// Do nothing; not encrypted or signed
@DoNotTouch
```

例如，這些註釋會簽署但不會加密 `PublicationYear` 屬性，且不會加密或簽署 `ISBN` 屬性值。

```
// Sign only (override the default)
@DoNotEncrypt
@DynamoDBAttribute(attributeName="PublicationYear")

// Do nothing (override the default)
@DoNotTouch
@DynamoDBAttribute(attributeName="ISBN")
```

### DynamoDBEncryptor 的屬性動作
<a name="attribute-action-default"></a>

若要在您直接使用 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) 時指定屬性動作，請建立 `HashMap` 物件，其中的名稱值組代表屬性名稱和指定的動作。

屬性動作的有效值會定義於 `EncryptionFlags` 列舉類型中。您可以同時使用 `ENCRYPT` 與 `SIGN`、單獨使用 `SIGN`，或省略兩者。不過，如果您`ENCRYPT`單獨使用 ，DynamoDB Encryption Client 會擲回錯誤。您無法加密您未簽署的屬性。

```
ENCRYPT
SIGN
```

**警告**  
請勿加密主索引鍵的屬性。它們必須保持純文字，以便 DynamoDB 可以在不執行完整資料表掃描的情況下找到項目。

如果您在加密內容中指定主金鑰，然後在任一主金鑰屬性的屬性動作`ENCRYPT`中指定 ，則 DynamoDB 加密用戶端會擲回例外狀況。

例如，下列 Java 程式碼會建立 `actions` HashMap，該 HashMap 會加密並簽署 `record` 項目中的所有屬性。例外狀況是分割索引鍵和排序索引鍵屬性 (已簽署但未加密)，以及未簽署或加密的 `test` 屬性。

```
final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN);
final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN);
final Map<String, Set<EncryptionFlags>> actions = new HashMap<>();

for (final String attributeName : record.keySet()) {
  switch (attributeName) {
    case partitionKeyName: // no break; falls through to next case
    case sortKeyName:
      // Partition and sort keys must not be encrypted, but should be signed
      actions.put(attributeName, signOnly);
      break;
    case "test":
      // Don't encrypt or sign
      break;
    default:
      // Encrypt and sign everything else
      actions.put(attributeName, encryptAndSign);
      break;
  }
}
```

然後，當您呼叫 的 [encryptRecord](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html#encryptRecord-java.util.Map-java.util.Map-com.amazonaws.services.dynamodbv2.datamodeling.encryption.EncryptionContext-) 方法時`DynamoDBEncryptor`，請將映射指定為 `attributeFlags` 參數的值。例如，`encryptRecord` 的這項呼叫會使用 `actions` 映射。

```
// Encrypt the plaintext record
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
```

## 覆寫表格名稱
<a name="override-table-name"></a>

在 DynamoDB 加密用戶端中，DynamoDB 資料表的名稱是傳遞給加密和解密方法的 [DynamoDB 加密內容](concepts.md#encryption-context)元素。當您加密或簽署資料表項目時，DynamoDB 加密內容會以密碼編譯方式繫結至加密文字，包括資料表名稱。如果傳遞至解密方法的 DynamoDB 加密內容與傳遞至加密方法的 DynamoDB 加密內容不相符，解密操作會失敗。

有時候，表格的名稱會發生變更，例如當您備份表格或執行[時間點復原時](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/PointInTimeRecovery.html)。當您解密或驗證這些項目的簽章時，您必須傳入用於加密和簽署項目的相同 DynamoDB 加密內容，包括原始資料表名稱。目前的表格名稱是不需要的。

當您使用 時`DynamoDBEncryptor`，您可以手動組合 DynamoDB 加密內容。不過，如果您使用的是 `DynamoDBMapper`， 會為您`AttributeEncryptor`建立 DynamoDB 加密內容，包括目前的資料表名稱。若要告訴 `AttributeEncryptor` 建立具有不同資料表名稱的加密內容，請使用 `EncryptionContextOverrideOperator`。

例如，下列程式碼會建立密碼編譯材料提供者 (CMP) 和 `DynamoDBEncryptor`。然後它會呼叫 `DynamoDBEncryptor` 的 `setEncryptionContextOverrideOperator` 方法。它使用覆寫一個表格名稱的 `overrideEncryptionContextTableName` 運算子。以這種方式設定時， `AttributeEncryptor`會建立包含 的 DynamoDB 加密內容`newTableName`，以取代 `oldTableName`。如需完整的範例，請參閱 [EncryptionContextOverridesWithDynamoDBMapper.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/EncryptionContextOverridesWithDynamoDBMapper.java)。

```
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);

encryptor.setEncryptionContextOverrideOperator(EncryptionContextOperators.overrideEncryptionContextTableName(
                oldTableName, newTableName));
```

當您呼叫 `DynamoDBMapper` (解密和驗證項目) 的載入方法時，您可以指定原始資料表名稱。

```
mapper.load(itemClass, DynamoDBMapperConfig.builder()
                .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(oldTableName))
                .build());
```

您也可以使用 `overrideEncryptionContextTableNameUsingMap` 運算子，該運算子會覆寫多個表格名稱。

表格名稱覆寫運算子通常用於解密資料和驗證簽章。不過，您可以在加密和簽署時，使用它們將 DynamoDB 加密內容中的資料表名稱設定為不同的值。

如果您使用的是 `DynamoDBEncryptor`，請勿使用表格名稱覆寫運算子。請改為使用原始表格名稱建立加密內容，並將其提交至解密方法。

# 適用於 Java 的 DynamoDB 加密用戶端的範例程式碼
<a name="java-examples"></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)。

下列範例示範如何使用適用於 Java 的 DynamoDB 加密用戶端來保護應用程式中的 DynamoDB 資料表項目。您可以在 GitHub 上 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) 儲存庫[的範例](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples)目錄中找到更多範例 （並自行提供）。

**Topics**
+ [使用 DynamoDBEncryptor](#java-example-ddb-encryptor)
+ [使用 DynamoDBMapper](#java-example-dynamodb-mapper)

## 使用 DynamoDBEncryptor
<a name="java-example-ddb-encryptor"></a>

這個範例說明如何使用較低層級的 [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) 搭配[直接 KMS 提供者](direct-kms-provider.md)。Direct KMS 提供者會在您指定的 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in AWS Key Management Service (AWS KMS) 下產生並保護其密碼編譯資料。

您可以使用任何相容的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) 搭配 `DynamoDBEncryptor`，而且可以使用直接 KMS 提供者搭配 `DynamoDBMapper` 與 [AttributeEncryptor](java-using.md#attribute-encryptor)。

**查看完整的程式碼範例**：[AwsKmsEncryptedItem.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)

步驟 1：建立直接 KMS 提供者  
建立具有指定區域的 AWS KMS 用戶端執行個體。然後，使用用戶端執行個體，以您偏好的 建立直接 KMS 提供者的執行個體 AWS KMS key。  
此範例使用 Amazon Resource Name (ARN) 來識別 AWS KMS key，但您可以使用[任何有效的金鑰識別符](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn)。  

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

步驟 2：建立項目  
這個範例會定義 `record` HashMap，其代表範例資料表項目。  

```
final String partitionKeyName = "partition_attribute";
final String sortKeyName = "sort_attribute";

final Map<String, AttributeValue> record = new HashMap<>();
record.put(partitionKeyName, new AttributeValue().withS("value1"));
record.put(sortKeyName, new AttributeValue().withN("55"));
record.put("example", new AttributeValue().withS("data"));
record.put("numbers", new AttributeValue().withN("99"));
record.put("binary", new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
record.put("test", new AttributeValue().withS("test-value"));
```

步驟 3：建立 DynamoDBEncryptor  
使用直接 KMS 提供者建立 `DynamoDBEncryptor` 的執行個體。  

```
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
```

步驟 4：建立 DynamoDB 加密內容  
[DynamoDB 加密內容](concepts.md#encryption-context)包含資料表結構及其加密和簽署方式的相關資訊。如果您使用 `DynamoDBMapper`，`AttributeEncryptor` 會為您建立加密細節。  

```
final String tableName = "testTable";

final EncryptionContext encryptionContext = new EncryptionContext.Builder()
    .withTableName(tableName)
    .withHashKeyName(partitionKeyName)
    .withRangeKeyName(sortKeyName)
    .build();
```

步驟 5：建立屬性動作物件  
[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)決定項目的哪些屬性會加密並簽署，哪些屬性只會簽署，以及哪些屬性不會加密或簽署。  
在 Java 中，若要指定屬性動作，您可建立屬性名稱和 `EncryptionFlags` 值組的 HashMap。  
例如，下列 Java 程式碼會建立 `actions` HashMap，其可加密並簽署 `record` 項目中的所有屬性，但是分割區索引鍵與排序索引鍵屬性 (簽署但不加密) 以及 `test` 屬性 (不簽署或加密) 除外。  

```
final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN);
final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN);
final Map<String, Set<EncryptionFlags>> actions = new HashMap<>();

for (final String attributeName : record.keySet()) {
  switch (attributeName) {
    case partitionKeyName: // fall through to the next case
    case sortKeyName:
      // Partition and sort keys must not be encrypted, but should be signed
      actions.put(attributeName, signOnly);
      break;
    case "test":
      // Neither encrypted nor signed
      break;
    default:
      // Encrypt and sign all other attributes
      actions.put(attributeName, encryptAndSign);
      break;
  }
}
```

步驟 6：將項目加密並簽署  
若要加密並簽署資料表項目，請在 `encryptRecord` 的執行個體上呼叫 `DynamoDBEncryptor` 方法。指定資料表項目 (`record`)、屬性動作 (`actions`) 及加密細節 (`encryptionContext`)。  

```
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
```

步驟 7：將項目放入 DynamoDB 資料表  
最後，將加密和簽署的項目放入 DynamoDB 資料表。  

```
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();
ddb.putItem(tableName, encrypted_record);
```

## 使用 DynamoDBMapper
<a name="java-example-dynamodb-mapper"></a>

下列範例示範如何搭配 [Direct KMS 提供者](direct-kms-provider.md)使用 DynamoDB 映射器協助程式類別。Direct KMS 提供者會在您指定的 AWS Key Management Service (AWS KMS) [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)中的 下產生並保護其密碼編譯資料。

您可以使用任何相容的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) 搭配 `DynamoDBMapper`，而且可以使用直接 KMS 提供者搭配較低層級的 `DynamoDBEncryptor`。

**查看完整的程式碼範例**：[AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java)

步驟 1：建立直接 KMS 提供者  
建立具有指定區域的 AWS KMS 用戶端執行個體。然後，使用用戶端執行個體，以您偏好的 建立直接 KMS 提供者的執行個體 AWS KMS key。  
此範例使用 Amazon Resource Name (ARN) 來識別 AWS KMS key，但您可以使用[任何有效的金鑰識別符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。  

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

步驟 2：建立 DynamoDB 加密程式和 DynamoDBMapper  
使用您在上一個步驟中建立的直接 KMS 提供者來建立 [DynamoDB 加密程式](java-using.md#attribute-encryptor)的執行個體。您需要執行個體化較低層級的 DynamoDB Encryptor，才能使用 DynamoDB Mapper。  
接著，建立 DynamoDB 資料庫的執行個體和映射器組態，並使用它們來建立 DynamoDB Mapper 的執行個體。  
使用 `DynamoDBMapper` 加入或編輯已簽署 (或已加密並簽署) 的項目時，請將其設定成[使用儲存行為](java-using.md#save-behavior) (例如 `PUT`) 納入所有屬性，如以下範例所示。否則，您將可能無法解密資料。

```
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp)
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();

DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
```

步驟 3：定義您的 DynamoDB 資料表  
接著，定義您的 DynamoDB 資料表。請使用註釋指定[屬性動作](java-using.md#attribute-actions-java)。此範例會建立代表資料表項目的 DynamoDB 資料表`ExampleTable`、 和 `DataPoJo`類別。  
該範例資料表的主索引鍵屬性將經過簽署但未加密。這包括了標註 `@DynamoDBHashKey` 的 `partition_attribute`，以及標註 `@DynamoDBRangeKey` 的 `sort_attribute`。  
凡是標註 `@DynamoDBAttribute` 的屬性 (例如 `some numbers`) 都將進行加密並簽署。例外狀況是使用 DynamoDB Encryption Client 定義的 `@DoNotEncrypt`（僅簽署） 或 `@DoNotTouch`（不加密或簽署） 加密註釋的屬性。例如，`leave me` 屬性由於設有 `@DoNotTouch` 註釋，其將不會進行加密或簽署。  

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String example;
  private long someNumbers;
  private byte[] someBinary;
  private String leaveMe;

  @DynamoDBHashKey(attributeName = "partition_attribute")
  public String getPartitionAttribute() {
    return partitionAttribute;
  }

  public void setPartitionAttribute(String partitionAttribute) {
    this.partitionAttribute = partitionAttribute;
  }

  @DynamoDBRangeKey(attributeName = "sort_attribute")
  public int getSortAttribute() {
    return sortAttribute;
  }

  public void setSortAttribute(int sortAttribute) {
    this.sortAttribute = sortAttribute;
  }

  @DynamoDBAttribute(attributeName = "example")
  public String getExample() {
    return example;
  }

  public void setExample(String example) {
    this.example = example;
  }

  @DynamoDBAttribute(attributeName = "some numbers")
  public long getSomeNumbers() {
    return someNumbers;
  }

  public void setSomeNumbers(long someNumbers) {
    this.someNumbers = someNumbers;
  }

  @DynamoDBAttribute(attributeName = "and some binary")
  public byte[] getSomeBinary() {
    return someBinary;
  }

  public void setSomeBinary(byte[] someBinary) {
    this.someBinary = someBinary;
  }

  @DynamoDBAttribute(attributeName = "leave me")
  @DoNotTouch
  public String getLeaveMe() {
    return leaveMe;
  }

  public void setLeaveMe(String leaveMe) {
    this.leaveMe = leaveMe;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ", sortAttribute="
        + sortAttribute + ", example=" + example + ", someNumbers=" + someNumbers
        + ", someBinary=" + Arrays.toString(someBinary) + ", leaveMe=" + leaveMe + "]";
  }
}
```

步驟 4：加密並儲存資料表項目  
現在，當您建立資料表項目並使用 DynamoDB Mapper 儲存該項目時，該項目會在新增至資料表之前自動加密和簽署。  
本範例定義的資料表項目名為 `record`。該項目儲存至資料表之前，其屬性將根據 `DataPoJo` 類別中的註釋進行加密與簽署。就本例而言，所有屬性除了 `PartitionAttribute`、`SortAttribute` 和 `LeaveMe` 以外都將加密並簽署。`PartitionAttribute` 和 `SortAttributes` 只會進行簽署，而 `LeaveMe` 屬性則完全未加密或簽署。  
若要加密並簽署 `record` 項目，然後將其加入至 `ExampleTable`，請呼叫 `DynamoDBMapper` 類別的 `save` 方法。由於您的 DynamoDB Mapper 已設定為使用`PUT`儲存行為，因此項目會使用相同的主索引鍵取代任何項目，而不是更新它。這可確保簽章相符，而且您從資料表取得該項目後便能將其解密。  

```
DataPoJo record = new DataPoJo();
record.setPartitionAttribute("is this");
record.setSortAttribute(55);
record.setExample("data");
record.setSomeNumbers(99);
record.setSomeBinary(new byte[]{0x00, 0x01, 0x02});
record.setLeaveMe("alone");

mapper.save(record);
```

# 適用於 Python 的 DynamoDB 加密用戶端
<a name="python"></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)。

本主題說明如何安裝和使用適用於 Python 的 DynamoDB Encryption Client。您可以在 GitHub 上的 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 儲存庫中找到程式碼 (包括完整和已測試的[範本程式碼](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples))，協助您開始使用。

**注意**  
適用於 Python 的 DynamoDB Encryption Client 版本 1.*x*.*x* 和 2.*x*.*x* 自 2022 年 7 月起處於[end-of-support階段](what-is-database-encryption-sdk.md#support)。盡快升級至較新的版本。

**Topics**
+ [先決條件](#python-prerequisites)
+ [安裝](#python-installation)
+ [使用適用於 Python 的 DynamoDB 加密用戶端](python-using.md)
+ [Python 範例](python-examples.md)

## 先決條件
<a name="python-prerequisites"></a>

安裝適用於 Python 的 Amazon DynamoDB 加密用戶端之前，請確定您有下列先決條件。

**支援的 Python 版本**  
Amazon DynamoDB Encryption Client for Python 3.3.0 版及更新版本需要 Python 3.8 或更新版本。若要下載 Python，請參閱 [Python 下載](https://www.python.org/downloads/)。  
舊版的 Amazon DynamoDB Encryption Client for Python 支援 Python 2.7 和 Python 3.4 及更新版本，但我們建議您使用最新版本的 DynamoDB Encryption Client。

**適用於 Python 的 pip 安裝工具**  
Python 3.6 和更新版本包含 **pip**，但您可能想要將其升級。如需升級或安裝 pip 的詳細資訊，請參閱 **pip** 文件中的[安裝](https://pip.pypa.io/en/latest/installation/)。

## 安裝
<a name="python-installation"></a>

使用 **pip** 安裝 Amazon DynamoDB Encryption Client for Python，如下列範例所示。

**若要安裝最新版本**  

```
pip install dynamodb-encryption-sdk
```

如需使用 **pip** 來安裝及升級套件的詳細資訊，請參閱[安裝套件](https://packaging.python.org/tutorials/installing-packages/)。

DynamoDB 加密用戶端在所有平台上都需要[密碼編譯程式庫](https://cryptography.io/en/latest/)。Windows 上所有版本的 **pip** 都將安裝並建置**密碼編譯**程式庫，而 Linux 上的 **pip** 8.1 和更新版本則會安裝並建置**密碼編譯**。如果您使用舊版 **pip**，而且您的 Linux 環境沒有建置**密碼編譯**程式庫所需的工具，您就需要加以安裝。如需詳細資訊，請參閱[在 Linux 上建置密碼編譯](https://cryptography.io/en/latest/installation/#building-cryptography-on-linux)。

您可以從 GitHub 上的 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 儲存庫取得最新的 DynamoDB Encryption Client 開發版本。

安裝 DynamoDB 加密用戶端後，請先查看本指南中的範例 Python 程式碼。

# 使用適用於 Python 的 DynamoDB 加密用戶端
<a name="python-using"></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 Encryption Client for Python 的某些功能，這些功能在其他程式設計語言實作中可能找不到。這些功能旨在讓您更輕鬆地以最安全的方式使用 DynamoDB 加密用戶端。若非遇到罕見的使用案例，我們都建議您使用這些功能。

如需使用 DynamoDB 加密用戶端進行程式設計的詳細資訊，請參閱本指南中的 [Python 範例](python-examples.md)、GitHub 上 aws-dynamodb-encryption-python 儲存庫中[的範例](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples)，以及 DynamoDB 加密用戶端的 [Python 文件](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/)。

**Topics**
+ [用戶端協助程式類別](#python-helpers)
+ [TableInfo 類別](#table-info)
+ [Python 中的屬性動作](#python-attribute-actions)

## 用戶端協助程式類別
<a name="python-helpers"></a>

DynamoDB Encryption Client for Python 包含數個用戶端協助程式類別，可鏡像 DynamoDB 的 Boto 3 類別。這些協助程式類別旨在讓您更輕鬆地將加密和簽署新增至現有的 DynamoDB 應用程式，並避免最常見的問題，如下所示：
+ 藉由將主索引鍵的覆寫動作新增至 [AttributeActions](#python-attribute-actions) 物件，或藉由在您的 `AttributeActions` 物件明確指示用戶端為主索引鍵加密時擲回例外狀況，以防止您將項目中的主索引鍵加密。如果 `AttributeActions` 物件中的預設動作為 `DO_NOTHING`，則用戶端協助程式類別會將該動作用於主索引鍵。否則會使用 `SIGN_ONLY`。
+ 建立 [TableInfo 物件](#python-helpers)，並根據對 [DynamoDB 的呼叫填入 DynamoDB 加密內容](concepts.md#encryption-context)。 DynamoDB 這有助於確保您的 DynamoDB 加密內容準確，且用戶端可以識別主金鑰。
+ 當您寫入 DynamoDB 資料表或從 DynamoDB 資料表讀取時`get_item`，支援透明加密和解密資料表項目的方法，例如 `put_item`和 。只有 `update_item` 方法不受支援。

您可以使用用戶端協助程式類別，而無須直接與較低層級的[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)互動。只有在需要於項目加密程式中設定進階選項時，才使用這些類別。

用戶端協助程式類別包括：
+ [EncryptedTable](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/table.html#module-dynamodb_encryption_sdk.encrypted.table) 適用於在 DynamoDB 中使用[資料表](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table)資源的應用程式，一次處理一個資料表。
+ [EncryptedResource](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/resource.html) 適用於在 DynamoDB 中使用[服務資源](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#service-resource)類別進行批次處理的應用程式。
+ [EncryptedClient](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/client.html) 適用於在 DynamoDB [中使用較低層級用戶端](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#client)的應用程式。

若要使用用戶端協助程式類別，呼叫者必須具有在目標資料表上呼叫 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 操作的許可。

## TableInfo 類別
<a name="table-info"></a>

[TableInfo](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/tools/structures.html#dynamodb_encryption_sdk.structures.TableInfo) 類別是代表 DynamoDB 資料表的協助程式類別，包含其主索引鍵和次要索引的欄位。它可協助您取得正確而即時的資料表相關資訊。

如果您使用的是[用戶端協助程式類別](#python-helpers)，其將為您建立並使用 `TableInfo` 物件。否則，您可以明確建立一個物件。如需範例，請參閱 [使用項目加密程式](python-examples.md#python-example-item-encryptor)。

當您在`TableInfo`物件上呼叫 `refresh_indexed_attributes`方法時，它會呼叫 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 操作來填入物件的屬性值。查詢資料表會比進行索引名稱的硬編碼可靠得多。`TableInfo` 類別也包含 `encryption_context_values` 屬性，提供 [DynamoDB 加密內容](concepts.md#encryption-context)所需的值。

若要使用 `refresh_indexed_attributes`方法，發起人必須具有在目標資料表上呼叫 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 操作的許可。

## Python 中的屬性動作
<a name="python-attribute-actions"></a>

[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)會告知項目加密程式要對項目的每個屬性執行什麼動作。若要指定 Python 中的屬性動作，請建立具有預設動作和特定屬性之任何例外狀況的 `AttributeActions` 物件。有效值會在 `CryptoAction` 列舉類型中加以定義。

**重要**  
使用屬性動作加密表格項目後，從資料模型新增或移除屬性可能會導致簽章驗證錯誤，讓您無法解密資料。如需更詳細的說明，請參閱[變更您的資料模型](data-model.md)。

```
DO_NOTHING = 0
SIGN_ONLY = 1
ENCRYPT_AND_SIGN = 2
```

例如，此 `AttributeActions` 物件會建立 `ENCRYPT_AND_SIGN` 作為所有屬性的預設值，並指定 `ISBN` 和 `PublicationYear` 屬性的例外狀況。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
        'ISBN': CryptoAction.DO_NOTHING,
        'PublicationYear': CryptoAction.SIGN_ONLY
    }
)
```

若您使用的是[用戶端協助程式類別](#python-helpers)，您不需要指定主索引鍵屬性的屬性動作。用戶端協助程式類別可防止您將主索引鍵加密。

若未使用用戶端協助程式類別，且預設動作為 `ENCRYPT_AND_SIGN`，則必須指定主索引鍵的動作。建議的主索引鍵動作為 `SIGN_ONLY`。若要加以簡化，請使用會對主索引鍵使用 SIGN\$1ONLY 的 `set_index_keys` 方法，或是在預設動作為 DO\$1NOTHING 時使用此動作。

**警告**  
請勿加密主索引鍵的屬性。它們必須保持純文字，以便 DynamoDB 可以在不執行完整資料表掃描的情況下找到項目。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
)
actions.set_index_keys(*table_info.protected_index_keys())
```

# 適用於 Python 的 DynamoDB 加密用戶端的範例程式碼
<a name="python-examples"></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)。

下列範例示範如何使用適用於 Python 的 DynamoDB 加密用戶端來保護應用程式中的 DynamoDB 資料。您可以在 GitHub 上 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) 儲存庫[的範例](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples)目錄中找到更多範例 （並自行提供）。

**Topics**
+ [使用 EncryptedTable 用戶端協助程式類別](#python-example-table)
+ [使用項目加密程式](#python-example-item-encryptor)

## 使用 EncryptedTable 用戶端協助程式類別
<a name="python-example-table"></a>

下列範例示範如何使用 [Direct KMS Provider](direct-kms-provider.md) 搭配`EncryptedTable`[用戶端協助程式類別](python-using.md#python-helpers)。此範例使用與以下[使用項目加密程式](#python-example-item-encryptor)範例相同的[密碼編譯資料提供者](DDBEC-legacy-concepts.md#concept-material-provider)。不過，其將使用 `EncryptedTable` 類別，而不是直接與較低層級的[項目加密程式](DDBEC-legacy-concepts.md#item-encryptor)互動。

比較這些範例，您就可以看見用戶端協助程式類別為您所做的事情。這包括建立 [DynamoDB 加密內容](concepts.md#encryption-context)，並確保主金鑰屬性一律已簽署，但從未加密。若要建立加密內容並探索主金鑰，用戶端協助程式類別會呼叫 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 操作。若要執行此程式碼，您必須擁有呼叫此作業的權利。

**查看完整的程式碼範例**：[aws\$1kms\$1encrypted\$1table.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py)

步驟 1：建立資料表  
首先，使用資料表名稱建立標準 DynamoDB 資料表的執行個體。  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

步驟 2：建立密碼編譯資料提供者  
建立您所選[密碼編譯資料提供者](crypto-materials-providers.md) (CMP) 的執行個體。  
本範例使用[直接 KMS 提供者](direct-kms-provider.md)，但您可以使用任何相容的 CMP。若要建立直接 KMS 提供者，請指定 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)。此範例使用 的 Amazon Resource Name (ARN) AWS KMS key，但您可以使用任何有效的金鑰識別符。  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

步驟 3：建立屬性動作物件  
[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)會告知項目加密程式要對項目的每個屬性執行什麼動作。這個範例中的 `AttributeActions` 物件會加密並簽署所有項目，但 `test` 屬性 (予以忽略) 除外。  
當您使用用戶端協助程式類別時，請勿指定主要索引鍵屬性的屬性動作。`EncryptedTable` 類別會簽署 (但絕不會加密) 主要索引鍵屬性。  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
```

步驟 4：建立已加密的資料表  
使用標準資料表、直接 KMS 提供者和屬性動作，來建立已加密的資料表。這個步驟可完成設定。  

```
encrypted_table = EncryptedTable(
    table=table,
    materials_provider=kms_cmp,
    attribute_actions=actions
)
```

步驟 5：在資料表中放入純文字項目  
當您在 上呼叫 `put_item`方法時`encrypted_table`，您的資料表項目會以透明方式加密、簽署，並新增至您的 DynamoDB 資料表。  
首先，定義資料表項目。  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
然後，在資料表中放入該項目。  

```
encrypted_table.put_item(Item=plaintext_item)
```

若要以加密形式從 DynamoDB 資料表取得項目，請在 `table` 物件上呼叫 `get_item`方法。若要取得已解密的項目，請在 `get_item` 物件上呼叫 `encrypted_table` 方法。

## 使用項目加密程式
<a name="python-example-item-encryptor"></a>

此範例說明如何在加密資料表[項目時，直接與 DynamoDB 加密用戶端](DDBEC-legacy-concepts.md#item-encryptor)中的項目加密程式互動，而不是使用與您項目加密程式互動的[用戶端協助程式類別](python-using.md#python-helpers)。 DynamoDB 

當您使用此技術時，您可以手動建立 DynamoDB 加密內容和組態物件 (`CryptoConfig`)。此外，您會在一個呼叫中加密項目，並將它們放在 DynamoDB 資料表中的個別呼叫中。這可讓您自訂`put_item`呼叫，並使用 DynamoDB 加密用戶端來加密和簽署從未傳送至 DynamoDB 的結構化資料。

本範例使用[直接 KMS 提供者](direct-kms-provider.md)，但您可以使用任何相容的 CMP。

**查看完整的程式碼範例**：[aws\$1kms\$1encrypted\$1item.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

步驟 1：建立資料表  
首先，使用資料表名稱建立標準 DynamoDB 資料表資源的執行個體。  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

步驟 2：建立密碼編譯資料提供者  
建立您所選[密碼編譯資料提供者](crypto-materials-providers.md) (CMP) 的執行個體。  
本範例使用[直接 KMS 提供者](direct-kms-provider.md)，但您可以使用任何相容的 CMP。若要建立直接 KMS 提供者，請指定 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)。此範例使用 的 Amazon Resource Name (ARN) AWS KMS key，但您可以使用任何有效的金鑰識別符。  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

步驟 3：使用 TableInfo 協助程式類別  
若要從 DynamoDB 取得資料表的相關資訊，請建立 [TableInfo](python-using.md#python-helpers) 協助程式類別的執行個體。當您直接使用項目加密程式時，您需要建立 `TableInfo` 執行個體及呼叫其方法。[用戶端協助程式類別](python-using.md#python-helpers)會為您執行此作業。  
`refresh_indexed_attributes` 方法`TableInfo`使用 [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) DynamoDB 操作來取得資料表的即時準確資訊。這包括其主要索引鍵及其本機和全域輔助索引。呼叫端必須具備呼叫 `DescribeTable` 的許可。  

```
table_info = TableInfo(name=table_name)
table_info.refresh_indexed_attributes(table.meta.client)
```

步驟 4：建立 DynamoDB 加密內容  
[DynamoDB 加密內容](concepts.md#encryption-context)包含資料表結構及其加密和簽署方式的相關資訊。此範例會明確建立 DynamoDB 加密內容，因為它會與項目加密程式互動。[用戶端協助程式類別](python-using.md#python-helpers)會為您建立 DynamoDB 加密內容。  
若要取得分割區索引鍵和排序索引鍵，您可以使用 [TableInfo](python-using.md#python-helpers) 協助程式類別的屬性。  

```
index_key = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
}

encryption_context = EncryptionContext(
    table_name=table_name,
    partition_key_name=table_info.primary_index.partition,
    sort_key_name=table_info.primary_index.sort,
    attributes=dict_to_ddb(index_key)
)
```

步驟 5：建立屬性動作物件  
[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)會告知項目加密程式要對項目的每個屬性執行什麼動作。這個範例中的 `AttributeActions` 物件會加密並簽署所有項目，但主要索引鍵屬性 (簽署但不加密) 和 `test` 屬性 (予以忽略) 除外。  
當您直接與項目加密程式互動且預設動作為 `ENCRYPT_AND_SIGN` 時，您必須為主要索引鍵指定替代動作。您可以使用 `set_index_keys` 方法，該方法針對主要索引鍵使用 `SIGN_ONLY`，或使用 `DO_NOTHING` (如果這是預設動作)。  
若要指定主索引鍵，此範例會使用 [TableInfo](python-using.md#python-helpers) 物件中的索引鍵，這會由對 DynamoDB 的呼叫填入。這項技巧比硬編碼主要索引鍵名稱還要安全。  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
actions.set_index_keys(*table_info.protected_index_keys())
```

步驟 6：建立項目的組態  
若要設定 DynamoDB 加密用戶端，請使用您剛在資料表項目的 [CryptoConfig](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/config.html) 組態中建立的物件。用戶端協助程式類別會為您建立 CryptoConfig。  

```
crypto_config = CryptoConfig(
    materials_provider=kms_cmp,
    encryption_context=encryption_context,
    attribute_actions=actions
)
```

步驟 7：將項目加密  
此步驟會加密並簽署項目，但不會將其放入 DynamoDB 資料表中。  
當您使用用戶端協助程式類別時，您的項目會以透明方式加密和簽署，然後在您呼叫協助程式類別的 `put_item`方法時新增至 DynamoDB 資料表。當您直接使用項目加密程式時，加密和放置動作都是獨立的。  
首先，建立純文字項目。  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_key': 55,
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
然後，將它加密並簽署。`encrypt_python_item` 方法需要 `CryptoConfig` 組態物件。  

```
encrypted_item = encrypt_python_item(plaintext_item, crypto_config)
```

步驟 8：在資料表中放入此項目  
此步驟會將加密和簽章的項目放入 DynamoDB 資料表。  

```
table.put_item(Item=encrypted_item)
```

若要檢視已加密的項目，請在原始 `get_item` 物件 (而非 `table` 物件) 上呼叫 `encrypted_table` 方法。不需進行驗證或解密，即可從 DynamoDB 資料表取得項目。

```
encrypted_item = table.get_item(Key=partition_key)['Item']
```

下圖顯示一部分已加密並簽署資料表項目的範例。

已加密的屬性值為二進位資料。主要索引鍵屬性 (`partition_attribute` 和 `sort_attribute`) 及 `test` 屬性的名稱和值都保持純文字形式。輸出也會顯示包含簽章 (`*amzn-ddb-map-sig*`) 的屬性和[資料描述屬性](DDBEC-legacy-concepts.md#legacy-material-description) (`*amzn-ddb-map-desc*`)。

![\[已加密並簽署的項目摘錄\]](http://docs.aws.amazon.com/zh_tw/database-encryption-sdk/latest/devguide/images/encrypted-item-closeup.png)


# 變更您的資料模型
<a name="data-model"></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#legacy-attribute-actions)，以告知 DynamoDB 加密用戶端要加密和簽署哪些屬性、要簽署哪些屬性 （但不要加密），以及要忽略哪些屬性。屬性動作不會儲存在加密的項目中，DynamoDB Encryption Client 不會自動更新您的屬性動作。

**重要**  
DynamoDB 加密用戶端不支援加密現有、未加密的 DynamoDB 資料表資料。

每當您變更資料模型時，也就是，當您新增或移除資料表項目中的屬性時，就可能發生錯誤。如果您指定的屬性動作並未考量項目中的所有屬性，此項目便無法如您預期的方式進行加密和簽署。更重要的是，如果您在加密項目時提供的屬性動作與您在解密項目時提供的屬性動作不同，則簽章驗證可能會失敗。

例如，如果用來加密項目的屬性動作告知要簽署 `test` 屬性，則項目中的簽章會包含 `test` 屬性。但是如果用來解密項目的屬性動作並未考量 `test` 屬性，則驗證會因為用戶端嘗試驗證不包含 `test` 屬性的簽章而失敗。

當多個應用程式讀取和寫入相同的 DynamoDB 項目時，這是一個特別的問題，因為 DynamoDB 加密用戶端必須計算所有應用程式中項目的相同簽章。對於任何分散式應用程式來說，這也是一個問題，因為屬性動作的變更必須傳播到所有主機。即使您的 DynamoDB 資料表是由一個主機在一個程序中存取，如果專案變得更複雜，建立最佳實務程序將有助於防止錯誤。

若要避免使您無法讀取資料表項目的簽章驗證錯誤，請使用下列指導。
+ [新增屬性](#add-attribute) — 如果新屬性變更您的屬性動作，請在項目中包含新屬性之前，先完全部署屬性動作變更。
+ [移除屬性](#remove-attribute) — 如果您停止在項目中使用屬性，請勿變更屬性動作。
+ 變更動作 — 在您使用屬性動作組態來加密資料表項目之後，您無法安全地變更現有屬性的預設動作或動作，而無需重新加密資料表中的每個項目。

簽章驗證錯誤可能非常難以解決，因此最好的方法是避免這些錯誤的發生。

**Topics**
+ [新增屬性](#add-attribute)
+ [移除屬性](#remove-attribute)

## 新增屬性
<a name="add-attribute"></a>

當您將新屬性新增至資料表項目時，您可能需要變更屬性動作。若要避免簽章驗證錯誤，我們建議您在兩階段的程序中實作此變更。在啟動第二個階段之前，請確認第一個階段已完成。

1. 在所有讀取或寫入資料表的應用程式中變更屬性動作。部署這些變更，並確認更新已傳播到所有目的地主機。

1. 將值寫入資料表項目中的新屬性。

這個兩階段的方法可確保所有應用程式和主機都具有相同的屬性動作，並在遇到新屬性之前計算相同的簽章。即使屬性的動作是*不執行任何動作* (不加密或簽署)，這個方法仍很重要，因為某些加密器的預設值是加密和簽署。

下列範例顯示此程序中第一個階段的程式碼。這些範例會新增項目屬性 `link`，此屬性會存放另一個資料表項目的連結。此連結必須維持純文字的形式，因此此範例會為其指派僅簽署動作。完全部署此變更，然後確認所有應用程式和主機都有新的屬性動作之後，您就可以開始在資料表項目中使用該 `link` 屬性。

------
#### [ Java DynamoDB Mapper ]

使用 `DynamoDB Mapper` 和 `AttributeEncryptor` 時，主要索引鍵 (簽署但不加密) 以外，所有屬性都預設會進行加密和簽署。若要指定僅簽署動作，請使用 `@DoNotEncrypt` 註釋。

此範例會針對新 `link` 屬性使用 `@DoNotEncrypt` 註釋。

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String link;

  @DynamoDBHashKey(attributeName = "partition_attribute")
  public String getPartitionAttribute() {
    return partitionAttribute;
  }
    
  public void setPartitionAttribute(String partitionAttribute) {
    this.partitionAttribute = partitionAttribute;
  }

  @DynamoDBRangeKey(attributeName = "sort_attribute")
  public int getSortAttribute() {
    return sortAttribute;
  }

  public void setSortAttribute(int sortAttribute) {
    this.sortAttribute = sortAttribute;
  }

  @DynamoDBAttribute(attributeName = "link")
  @DoNotEncrypt
  public String getLink() {
    return link;
  }

  public void setLink(String link) {
    this.link = link;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ",
        sortAttribute=" + sortAttribute + ",
        link=" + link + "]";
  }
}
```

------
#### [ Java DynamoDB encryptor ]

 在較低層級的 DynamoDB 加密程式中，您必須為每個屬性設定動作。此範例使用 switch 陳述式，其中預設值為 `encryptAndSign`，而且會針對分割索引鍵、排序索引鍵和新 `link` 屬性指定例外狀況。在此範例中，如果在使用連結屬性程式碼之前未將其完全部署，則某些應用程式會加密並簽署此連結屬性，但其他應用程式則僅簽署此連結屬性。

```
for (final String attributeName : record.keySet()) {
    switch (attributeName) {
        case partitionKeyName:
            // fall through to the next case
        case sortKeyName:
            // partition and sort keys must be signed, but not encrypted
            actions.put(attributeName, signOnly);
            break;
        case "link":
            // only signed
            actions.put(attributeName, signOnly);
            break;
        default:
            // Encrypt and sign all other attributes
            actions.put(attributeName, encryptAndSign);
            break;
    }
}
```

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

在適用於 Python 的 DynamoDB 加密用戶端中，您可以為所有屬性指定預設動作，然後指定例外狀況。

若您使用的是 Python [用戶端協助程式類別](python-using.md#python-helpers)，您不需要指定主索引鍵屬性的屬性動作。用戶端協助程式類別可防止您將主索引鍵加密。但是，如果您不使用用戶端協助程式類別，則必須在您的分割區索引鍵和排序索引鍵上設定 SIGN\$1ONLY 動作。如果您不小心加密了分割區或排序索引鍵，您將無法在沒有進行完整資料表掃描的情況下復原資料。

此範例會指定新 `link` 屬性 (取得 `SIGN_ONLY` 動作) 的例外狀況。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
      'example': CryptoAction.DO_NOTHING,  
      'link': CryptoAction.SIGN_ONLY
    }
)
```

------

## 移除屬性
<a name="remove-attribute"></a>

如果您在已使用 DynamoDB Encryption Client 加密的項目中不再需要 屬性，您可以停止使用 屬性。但是，請勿刪除或變更該屬性的動作。如果您這樣做，然後遇到具有該屬性的項目，則針對該項目計算的簽章將不符合原始簽章，且簽章驗證將會失敗。

雖然您可能想要從程式碼中移除屬性的所有追蹤，但請新增註解，指出該項目已不再使用，而不是將其刪除。即使您執行完整資料表掃描以刪除該屬性的所有執行個體，具有該屬性的加密項目可能會被快取或在組態中的某處處理中。

# 故障診斷 DynamoDB Encryption Client 應用程式的問題
<a name="troubleshooting"></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 加密用戶端時可能遇到的問題，並提供解決這些問題的建議。

若要提供 DynamoDB 加密用戶端的意見回饋，請在 [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) 或 [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) GitHub 儲存庫中提出問題。

若要提供有關此文件的意見回饋，請使用任何頁面上的意見回饋連結。

**Topics**
+ [存取遭拒](#kms-permissions)
+ [簽章驗證失敗](#change-data-model)
+ [舊版全域資料表的問題](#fix-global-tables)
+ [最近提供者的效能不佳](#mrp-ttl-delay)

## 存取遭拒
<a name="kms-permissions"></a>

**問題**：您的應用程式遭拒，無法存取其所需的資源。

**建議**：了解必要的許可，並將這些許可新增至您的應用程式執行所在的安全性細節。

**詳細資訊**

若要執行使用 DynamoDB 加密用戶端程式庫的應用程式，發起人必須具有使用其元件的許可。否則他們會遭拒，無法存取所需的元素。
+ DynamoDB 加密用戶端不需要 Amazon Web Services (AWS) 帳戶或依賴任何 AWS 服務。不過，如果您的應用程式使用 AWS，您需要 [AWS 帳戶](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)和[具有帳戶使用許可的使用者](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html)。
+ DynamoDB 加密用戶端不需要 Amazon DynamoDB。不過，如果使用 用戶端的應用程式建立 DynamoDB 資料表、將項目放入資料表或從資料表取得項目，呼叫者必須具有在您的 中使用所需 DynamoDB 操作的許可 AWS 帳戶。如需詳細資訊，請參閱《*Amazon DynamoDB 開發人員指南*》中的[存取控制主題](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/access-control-overview.html)。
+ 如果您的應用程式在 DynamoDB Encryption Client for Python 中使用[用戶端協助程式類別](python-using.md#python-helpers)，呼叫者必須具有呼叫 DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) 操作的許可。
+ DynamoDB 加密用戶端不需要 AWS Key Management Service (AWS KMS)。不過，如果您的應用程式使用[直接 KMS 資料提供者](direct-kms-provider.md)，或它使用[最近提供者](most-recent-provider.md)搭配使用 的提供者存放區 AWS KMS，呼叫者必須具有使用 AWS KMS [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) 和 [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 操作的許可。

## 簽章驗證失敗
<a name="change-data-model"></a>

**問題**：項目因為簽章驗證失敗而無法解密。此項目也無法如您所願進行加密和簽署。

**建議**：確保您提供的屬性動作會考量項目中的所有屬性。將項目解密時，請務必提供與用來解密項目之動作相符的屬性動作。

**詳細資訊**

您提供的[屬性動作](DDBEC-legacy-concepts.md#legacy-attribute-actions)會告知 DynamoDB 加密用戶端要加密和簽署的屬性、要簽署的屬性 （但不加密），以及要忽略的屬性。

如果您指定的屬性動作並未考量項目中的所有屬性，此項目便無法如您預期的方式進行加密和簽署。如果您在加密項目時提供的屬性動作與您在解密項目時提供的屬性動作不同，則簽章驗證可能會失敗。這是一個特殊問題，出現於新屬性動作尚未傳播到所有主機的分散式應用程式中。

簽章驗證錯誤很難解決。如需協助防範其發生，請在變更資料模型時採取額外的預防措施。如需詳細資訊，請參閱[變更您的資料模型](data-model.md)。

## 舊版全域資料表的問題
<a name="fix-global-tables"></a>

**問題**：舊版 Amazon DynamoDB 全域資料表中的項目無法解密，因為簽章驗證失敗。

**建議**：設定屬性動作，讓保留的複寫欄位不會加密或簽署。

**詳細資訊**

您可以使用 DynamoDB 加密用戶端搭配 [DynamoDB 全域資料表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)。我們建議您使用具有[多區域 KMS 金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)的全域資料表，並將 KMS 金鑰複寫到複寫全域資料表的所有 AWS 區域 。

從全域資料表 [2019.11.21 版](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html)開始，您可以將全域資料表與 DynamoDB 加密用戶端搭配使用，而不需要任何特殊組態。不過，如果您使用全域資料表 [2017.11.29 版](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html)，您必須確保保留的複寫欄位未加密或簽署。

如果您使用的是全域資料表 2017.11.29 版，則必須在 `DO_NOTHING` [Java](java-using.md#attribute-actions-java) 或 [Python](python-using.md#python-attribute-actions) `@DoNotTouch`中將下列屬性的屬性動作設定為 。
+ `aws:rep:deleting`
+ `aws:rep:updatetime`
+ `aws:rep:updateregion`

如果您使用任何其他版本的全域資料表，則不需要任何動作。

## 最近提供者的效能不佳
<a name="mrp-ttl-delay"></a>

**問題**：您的應用程式回應較差，特別是在更新至較新版本的 DynamoDB 加密用戶端之後。

**建議**：調整time-to-live值和快取大小。

**詳細資訊**

最新提供者旨在透過允許有限的密碼編譯資料重複使用，改善使用 DynamoDB 加密用戶端的應用程式效能。當您為應用程式設定最新提供者時，您必須平衡改善的效能與快取和重複使用引起的安全問題。

在較新版本的 DynamoDB 加密用戶端中，time-to-live(TTL) 值會決定可使用快取密碼編譯材料提供者 CMPs) 的時間長度。TTL 也會判斷最近提供者檢查 CMP 新版本的頻率。

如果您的 TTL 太長，您的應用程式可能會違反您的業務規則或安全標準。如果您的 TTL 太短，經常呼叫提供者存放區可能會導致提供者存放區調節來自您應用程式和其他共用您服務帳戶的應用程式的請求。若要解決此問題，請將 TTL 和快取大小調整為符合您延遲和可用性目標，並符合安全標準的值。如需詳細資訊，請參閱[設定time-to-live值](most-recent-provider.md#most-recent-provider-ttl)。