

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

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