

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

# 创建有效的分支密钥
<a name="create-branch-keys"></a>

*分支密钥*是派生自分支密钥的数据密钥 AWS KMS key ， AWS KMS 分层密钥环使用该密钥来减少调用的次数。 AWS KMS*活动*分支密钥为最新分支密钥版本。分层密钥环为每个加密请求生成唯一的数据密钥，并使用从活动分支密钥派生的唯一包装密钥对每个数据密钥进行加密。

要创建新的活动分支密钥，必须[静态配置](keystore-actions.md#static-keystore)密钥存储操作。 `CreateKey`是一项特权操作，用于将密钥库操作配置中指定的 KMS 密钥 ARN 添加到密钥库许可名单中。然后，使用 KMS 密钥生成新的活动分支密钥。我们建议限制对此操作的访问权限，因为将 KMS 密钥添加到密钥存储库后，便无法将其删除。

我们建议通过应用程序控制平面中的 KeyStore 管理界面使用该`CreateKey`操作。这种方法符合密钥管理的最佳实践。

不要在数据平面中创建分支密钥。这种做法可能导致：
+ 拨打不必要的电话 AWS KMS
+  AWS KMS 在高并发环境中多次并发调用
+ 多次 TransactWriteItems 调用后备的 DynamoDB 表。

该`CreateKey`操作在`TransactWriteItems`调用中包括条件检查，以防止覆盖现有的分支密钥。但是，在数据平面中创建密钥仍可能导致资源使用效率低下和潜在的性能问题。

您可以将密钥存储库中的一个 KMS 密钥列入许可名单，也可以通过更新您在密钥存储操作配置中指定的 KMS 密钥 ARN 并再次调用来允许列入多个 KMS 密钥。`CreateKey`如果您将多个 KMS 密钥列入许可名单，则您的密钥存储用户应配置其密钥存储操作以供发现，以便他们可以使用他们有权访问的密钥存储库中的任何允许列表的密钥。有关更多信息，请参阅 [配置密钥存储操作](keystore-actions.md)。

**所需的权限**  
要创建分支密钥，您需要拥有密[钥存储操作中指定的 KMS 密钥的 kms: GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) [和 kms: ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html) 权限。

**创建分支密钥**  
以下操作使用您在密钥[存储操作配置中指定的 KMS 密钥创建新的活动分支密钥，并将活动分支密钥添加到用作密钥存储](keystore-actions.md#static-keystore)的 DynamoDB 表中。

调用 `CreateKey` 时，您可以选择指定以下可选值。
+ `branchKeyIdentifier`：定义自定义 `branch-key-id`。

  要创建自定义 `branch-key-id`，还必须加入包含 `encryptionContext` 参数的其他加密上下文。
+ `encryptionContext`[: 定义一组可选的非秘密密钥值对，用于在 kms: 调用中包含的加密上下文中提供额外的经过身份验证的数据 (AAD)。GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html)

  此额外加密上下文带有 `aws-crypto-ec:` 前缀。

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

```
final Map<String, String> additionalEncryptionContext = Collections.singletonMap("Additional Encryption Context for",
	         "custom branch key id");
	             
	 final String BranchKey = keystore.CreateKey(
	         CreateKeyInput.builder()
	                 .branchKeyIdentifier(custom-branch-key-id) //OPTIONAL
	                 .encryptionContext(additionalEncryptionContext) //OPTIONAL              
	                 .build()).branchKeyIdentifier();
```

------
#### [ C\$1 / .NET ]

```
var additionalEncryptionContext = new Dictionary<string, string>();
	 additionalEncryptionContext.Add("Additional Encryption Context for", "custom branch key id");
	         
	 var branchKeyId = keystore.CreateKey(new CreateKeyInput
	 {
	     BranchKeyIdentifier = "custom-branch-key-id", // OPTIONAL
	     EncryptionContext = additionalEncryptionContext // OPTIONAL
	 });
```

------
#### [ Rust ]

```
let additional_encryption_context = HashMap::from([
    ("Additional Encryption Context for".to_string(), "custom branch key id".to_string())
]);

let branch_key_id = keystore.create_key()
    .branch_key_identifier("custom-branch-key-id") // OPTIONAL
    .encryption_context(additional_encryption_context) // OPTIONAL
    .send()
    .await?
    .branch_key_identifier
    .unwrap();
```

------

首先，`CreateKey` 操作生成以下值。
+ 适用于 `branch-key-id` 的版本 4 [通用唯一标识](https://www.ietf.org/rfc/rfc4122.txt)（UUID）（除非您指定了自定义 `branch-key-id`）。
+ 适用于分支密钥版本的版本 4 UUID
+ `timestamp` 必须采用协调世界时（UTC）[ISO 8601 日期和时间格式](https://www.iso.org/iso-8601-date-and-time-format.html)。

然后，该`CreateKey`操作GenerateDataKeyWithoutPlaintext使用以下[请求调用 kms:](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html)。

```
{
	    "EncryptionContext": { 
	       "branch-key-id" : "branch-key-id",
	       "type" : "type",
	       "create-time" : "timestamp",
	       "tablename" : "the logical table name for your key store",
	       "kms-arn" : the KMS key ARN,
	       "hierarchy-version" : "1",
	       "aws-crypto-ec:contextKey": "contextValue"
	    },
	    "KeyId": "the KMS key ARN you specified in your key store actions",
	    "NumberOfBytes": "32"
	 }
```

**注意**  
即使您尚未配置数据库的[可搜索加密](searchable-encryption.md)，`CreateKey` 操作也会创建活动分支密钥和信标密钥。两个密钥都存储在您的密钥库中。有关更多信息，请参阅[使用分层密钥环进行可搜索加密](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)。

接下来，该`CreateKey`操作调用 [km ReEncrypt s:](https://docs.aws.amazon.com/kms/latest/APIReference/AAPI_ReEncrypt.html)，通过更新加密上下文为分支密钥创建活动记录。

最后，该`CreateKey`操作调用 [ddb: TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html) 来编写一个新项目，该项目将保留您在**步骤 2** 中创建的表中的分支密钥。项目具有以下属性。

```
{
	     "branch-key-id" : branch-key-id,
	     "type" : "branch:ACTIVE",
	     "enc" : the branch key returned by the GenerateDataKeyWithoutPlaintext call,
	     "version": "branch:version:the branch key version UUID",
	     "create-time" : "timestamp",
	     "kms-arn" : "the KMS key ARN you specified in Step 1",
	     "hierarchy-version" : "1",
	     "aws-crypto-ec:contextKey": "contextValue"
 }
```