

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

# 建立作用中分支金鑰
<a name="create-branch-keys"></a>

*分支金鑰*是從 AWS KMS 衍生的資料金鑰 AWS KMS key ，階層式 keyring 會使用此金鑰來減少對 進行的呼叫數量 AWS KMS。*作用中*分支金鑰是最新的分支金鑰版本。階層式 keyring 會為每個加密請求產生唯一的資料金鑰，並使用衍生自作用中分支金鑰的唯一包裝金鑰來加密每個資料金鑰。

若要建立新的作用中分支金鑰，您必須[靜態設定](keystore-actions.md#static-keystore)金鑰存放區動作。 `CreateKey` 是一種特殊權限操作，可將金鑰存放區動作組態中指定的 KMS 金鑰 ARN 新增至金鑰存放區允許清單。然後，KMS 金鑰會用來產生新的作用中分支金鑰。我們建議您限制對此操作的存取，因為一旦 KMS 金鑰新增至金鑰存放區，就無法刪除它。

我們建議您透過應用程式控制平面中的 KeyStore Admin 界面使用 `CreateKey`操作。此方法符合金鑰管理的最佳實務。

請勿在資料平面中建立分支金鑰。此實務可能會導致：
+ 對 進行不必要的呼叫 AWS KMS
+ 在高並行環境中對 AWS KMS 的多個並行呼叫
+ 對後端 DynamoDB 資料表的多個 TransactWriteItems 呼叫。

`CreateKey` 操作會在`TransactWriteItems`呼叫中包含條件檢查，以防止覆寫現有的分支金鑰。不過，在資料平面中建立金鑰仍可能導致資源使用效率低下和潛在的效能問題。

您可以在金鑰存放區中允許列出一個 KMS 金鑰，也可以更新您在金鑰存放區動作組態中指定的 KMS 金鑰 ARN 並`CreateKey`再次呼叫，以允許列出多個 KMS 金鑰。如果您允許列出多個 KMS 金鑰，您的金鑰存放區使用者應該為探索設定其金鑰存放區動作，以便他們可以使用他們有權存取的金鑰存放區中任何允許列出的金鑰。如需詳細資訊，請參閱[設定金鑰存放區動作](keystore-actions.md)。

**所需的 許可**  
若要建立分支金鑰，您需要[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) 許可。

**建立分支金鑰**  
下列操作會使用您在金鑰[存放區動作組態中指定的](keystore-actions.md#static-keystore) KMS 金鑰建立新的作用中分支金鑰，並將作用中分支金鑰新增至做為金鑰存放區的 DynamoDB 資料表。

當您呼叫 時`CreateKey`，您可以選擇指定下列選用值。
+ `branchKeyIdentifier`：定義自訂 `branch-key-id`。

  若要建立自訂 `branch-key-id`，您還必須在 `encryptionContext` 參數中包含其他加密內容。
+ `encryptionContext`：定義一組選用的非秘密金鑰/值對，在 [kms:GenerateDataKeyWithoutPlaintext](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyWithoutPlaintext.html) 呼叫中包含的加密內容中提供額外的驗證資料 (AAD)。

  此額外的加密內容會以 `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`操作會產生下列值。
+ 第 4 版[的通用唯一識別符](https://www.ietf.org/rfc/rfc4122.txt) (UUID) `branch-key-id`（除非您指定了自訂 `branch-key-id`)。
+ 分支金鑰版本的第 4 版 UUID
+ ISO [8601 日期和時間格式](https://www.iso.org/iso-8601-date-and-time-format.html)`timestamp`的 ，以國際標準時間 (UTC) 為單位。

然後， `CreateKey`操作會使用下列請求呼叫 [kms:GenerateDataKeyWithoutPlaintext](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"
	 }
```

**注意**  
`CreateKey` 操作會建立作用中分支金鑰和信標金鑰，即使您尚未將資料庫設定為[可搜尋加密](searchable-encryption.md)。這兩個金鑰都存放在您的金鑰存放區中。如需詳細資訊，請參閱[使用階層式 keyring 進行可搜尋加密](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)。

接著， `CreateKey`操作會呼叫 [kms:ReEncrypt](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"
 }
```