

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

# 適用於 C 的 AWS Encryption SDK
<a name="c-language"></a>

為在 C 中編寫應用程式的開發人員 適用於 C 的 AWS Encryption SDK 提供用戶端加密程式庫。它也可以作為在高階程式設計語言 AWS Encryption SDK 中實作 的基礎。

與 的所有實作一樣 AWS Encryption SDK， 適用於 C 的 AWS Encryption SDK 提供進階資料保護功能。這些功能包括[信封加密](concepts.md#envelope-encryption)、額外的驗證資料 (AAD) 以及安全、已認證的對稱金鑰[演算法套件](concepts.md#crypto-algorithm)，例如 256 位元 AES-GCM 搭配金鑰衍生和簽署。

的所有語言特定實作 AWS Encryption SDK 皆可完全互通。例如，您可以使用 加密資料 適用於 C 的 AWS Encryption SDK ，並使用[任何支援的語言實作](programming-languages.md)解密資料，包括 [AWS Encryption CLI](crypto-cli.md)。

 適用於 C 的 AWS Encryption SDK 需要 適用於 C\$1\$1 的 AWS SDK 與 AWS Key Management Service (AWS KMS) 互動。只有在您使用選用的 [AWS KMS keyring](use-kms-keyring.md) 時，才需要使用它。不過， AWS Encryption SDK 不需要 AWS KMS 或任何其他 AWS 服務。

**進一步了解**
+ 如需使用 進行程式設計的詳細資訊 適用於 C 的 AWS Encryption SDK，請參閱 [C 範例](c-examples.md)、GitHub 上 [aws-encryption-sdk-c 儲存庫](https://github.com/aws/aws-encryption-sdk-c/)中[的範例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)，以及 [適用於 C 的 AWS Encryption SDK API 文件](https://aws.github.io/aws-encryption-sdk-c/html/)。
+ 如需如何使用 適用於 C 的 AWS Encryption SDK 加密資料的討論，以便您可以在多個區域中解密資料 AWS 區域，請參閱 AWS 安全部落格中的[如何使用 C AWS Encryption SDK 中的 解密多個區域中的加密文字](https://aws.amazon.com/blogs/security/how-to-decrypt-ciphertexts-multiple-regions-aws-encryption-sdk-in-c/)。

**Topics**
+ [安裝](c-language-installation.md)
+ [使用 C 開發套件](c-language-using.md)
+ [範例](c-examples.md)

# 安裝 適用於 C 的 AWS Encryption SDK
<a name="c-language-installation"></a>

安裝最新版本的 適用於 C 的 AWS Encryption SDK。

**注意**  
所有 適用於 C 的 AWS Encryption SDK 早於 2.0.0 的 版本都處於[end-of-support階段](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)。  
您可以從 2.0.*x* 版和更新版本安全地更新至最新版本的 ， 適用於 C 的 AWS Encryption SDK 而不需要變更任何程式碼或資料。不過，2.0.*x* 版中引入[的新安全功能](about-versions.md#version-2)無法回溯相容。若要從 1.7.*x* 之前的版本更新至 2.0.*x* 及更新版本，您必須先更新至最新的 1 適用於 C 的 AWS Encryption SDK.*x* 版本。如需詳細資訊，請參閱[遷移您的 AWS Encryption SDK](migration.md)。

您可以在 [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) 儲存庫的 適用於 C 的 AWS Encryption SDK [README 檔案中](https://github.com/aws/aws-encryption-sdk-c/#readme)找到安裝和建置 的詳細說明。其中包括在 Amazon Linux、Ubuntu、macOS 和 Windows 平台上建置 的說明。

開始之前，請先決定您是否要在 中使用 [AWS KMS keyring](use-kms-keyring.md) AWS Encryption SDK。如果您使用 AWS KMS keyring，則需要安裝 適用於 C\$1\$1 的 AWS SDK。需要 AWS SDK 才能與 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)() 互動AWS KMS。當您使用 AWS KMS keyring 時， AWS Encryption SDK 會使用 AWS KMS 來產生和保護保護您資料的加密金鑰。

 適用於 C\$1\$1 的 AWS SDK 如果您使用其他 keyring 類型，例如原始 AES keyring、原始 RSA keyring 或不包含 AWS KMS keyring 的多 keyring，則不需要安裝 。不過，使用原始 keyring 類型時，您需要產生並保護自己的原始包裝金鑰。

如果您在安裝時遇到問題，請在 `aws-encryption-sdk-c`儲存庫中[提出問題](https://github.com/aws/aws-encryption-sdk-c/issues)，或使用此頁面上的任何意見回饋連結。

# 使用 適用於 C 的 AWS Encryption SDK
<a name="c-language-using"></a>

本主題說明其他程式設計語言實作 適用於 C 的 AWS Encryption SDK 中不支援的部分 功能。

本節中的範例示範如何使用 [2.0.*x* 版](about-versions.md)和更新版本 適用於 C 的 AWS Encryption SDK。如需使用舊版的範例，請在 GitHub 上 [aws-encryption-sdk-c 儲存庫](https://github.com/aws/aws-encryption-sdk-c/)的[版本](https://github.com/aws/aws-encryption-sdk-c/releases)清單中找到您的版本。

如需使用 進行程式設計的詳細資訊 適用於 C 的 AWS Encryption SDK，請參閱 [C 範例](c-examples.md)、GitHub 上 [aws-encryption-sdk-c 儲存庫](https://github.com/aws/aws-encryption-sdk-c/)中[的範例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)，以及 [適用於 C 的 AWS Encryption SDK API 文件](https://aws.github.io/aws-encryption-sdk-c/html/)。

另請參閱：[Keyring](choose-keyring.md)

**Topics**
+ [加密和解密資料的模式](#c-language-using-pattern)
+ [參考計數](#c-language-using-release)

## 加密和解密資料的模式
<a name="c-language-using-pattern"></a>

當您使用 時 適用於 C 的 AWS Encryption SDK，請遵循類似如下的模式：建立 [keyring](concepts.md#keyring)、建立使用 keyring 的 [CMM](concepts.md#crypt-materials-manager)、建立使用 CMM （和 keyring) 的工作階段，然後處理工作階段。

1. 載入錯誤字串。  
在 C 或 C\$1\$1 程式碼中呼叫 `aws_cryptosdk_load_error_strings()`方法。它會載入對偵錯非常有用的錯誤資訊。  
您只需呼叫一次，例如在您的`main`方法中。  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

2. 建立 keyring。  
使用您想用來加密資料金鑰的包裝金鑰來設定 [keyring](concepts.md#keyring)。此範例使用 [AWS KMS keyring](use-kms-keyring.md) 搭配 keyring AWS KMS key，但您可以在其位置使用任何類型的 keyring。  
若要在 AWS KMS key 的加密 keyring 中識別 適用於 C 的 AWS Encryption SDK，請指定[金鑰 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 或[別名 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn)。在解密 Keyring 中，您必須使用金鑰 ARN。如需詳細資訊，請參閱[在 AWS KMS keyring AWS KMS keys 中識別](use-kms-keyring.md#kms-keyring-id)。  

```
const char * KEY_ARN = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"    
struct aws_cryptosdk_keyring *kms_keyring = 
       Aws::Cryptosdk::KmsKeyring::Builder().Build(KEY_ARN);
```

3. 建立工作階段。  
在 中 適用於 C 的 AWS Encryption SDK，您可以使用*工作階段*來加密單一純文字訊息或解密單一加密文字訊息，無論其大小為何。此工作階段在整個處理過程中會維護訊息的狀態。  
使用分配器、keyring 和模式來設定您的工作階段：`AWS_CRYPTOSDK_ENCRYPT` 或 `AWS_CRYPTOSDK_DECRYPT`。如果您需要變更工作階段的模式，請使用 `aws_cryptosdk_session_reset` 方法。  
當您使用 keyring 建立工作階段時， 適用於 C 的 AWS Encryption SDK 會自動為您建立預設密碼編譯資料管理員 (CMM)。您不需要建立、維護或銷毀此物件。  
例如，以下工作階段使用在步驟 1 中定義的分配器和 keyring。當您加密資料時，模式為 `AWS_CRYPTOSDK_ENCRYPT`。  

```
struct aws_cryptosdk_session * session = aws_cryptosdk_session_new_from_keyring_2(allocator, AWS_CRYPTOSDK_ENCRYPT, kms_keyring);
```

4. 加密或解密資料。  
若要在工作階段中處理資料，請使用 `aws_cryptosdk_session_process` 方法。如果輸入緩衝區夠大以容納整個純文字，而輸出緩衝區夠大以容納整個加密文字，您可以呼叫 `aws_cryptosdk_session_process_full`。不過，如果您需要處理串流資料，您可以在迴圈`aws_cryptosdk_session_process`中呼叫 。如需範例，請參閱 [file\$1streaming.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/file_streaming.cpp) 範例。`aws_cryptosdk_session_process_full` 已在 1.9.*x* 和 2.2.*x* AWS Encryption SDK 版中推出。  
當工作階段設定為加密資料時，純文字欄位描述輸入，加密文字欄位描述輸出。`plaintext` 欄位保留您想要加密的訊息，`ciphertext` 欄位取得加密方法所傳回的[加密訊息](message-format.md)。  

```
/* Encrypting data */
aws_cryptosdk_session_process_full(session,
                                   ciphertext,
                                   ciphertext_buffer_size,
                                   &ciphertext_length,
                                   plaintext,
                                   plaintext_length)
```
當工作階段設定為解密資料時，加密文字欄位描述輸入，純文字欄位描述輸出。`ciphertext` 欄位保留加密方法所傳回的[已加密訊息](message-format.md)，`plaintext` 欄位取得解密方法傳回的純文字訊息。  
若要解密資料，請呼叫 `aws_cryptosdk_session_process_full` 方法。  

```
/* Decrypting data */
aws_cryptosdk_session_process_full(session,
                                   plaintext,
                                   plaintext_buffer_size,
                                   &plaintext_length,
                                   ciphertext,
                                   ciphertext_length)
```

## 參考計數
<a name="c-language-using-release"></a>

為了防止記憶體流失，當您使用完您建立的所有物件參考時，請務必將其釋出。否則會造成記憶體失流。此開發套件提供方法讓您輕鬆這樣做。

每當您使用下列其中一個子物件建立父物件時，父物件會取得並維護對子物件的參考，如下所示：
+ [keyring](concepts.md#keyring)，例如，使用 keyring 建立工作階段
+ 預設[密碼編譯資料管理員](concepts.md#crypt-materials-manager) (CMM)，例如使用預設 CMM 建立工作階段或自訂 CMM
+ [資料金鑰快取](data-key-caching.md)，例如，使用 keyring 和快取建立快取 CMM

除非您需要對子物件的獨立參考，否則您可以在建立父物件後立即釋出對子物件的參考。在銷毀父物件時，對子物件的其餘參考即會釋出。此模式可確保只在您需要的一段時間內維護每個物件的參考，您不會因為參考未釋放而流失記憶體。

您只需負責釋出您明確建立的子物件參考。您不需負責管理 SDK 為您建立的任何物件的參考。如果 SDK 建立物件，例如 `aws_cryptosdk_caching_cmm_new_from_keyring`方法新增至工作階段的預設 CMM，則 SDK 會管理物件及其參考的建立和銷毀。

在下列範例中，當您使用 [keyring](concepts.md#keyring) 建立工作階段，該工作階段會取得 keyring 的參考，並保留該參考，直到工作階段銷毀為止。如果您不需要保有 keyring 的其他參考，您可以使用 `aws_cryptosdk_keyring_release` 方法在建立工作階段後立即釋出 keyring 物件。此方法可遞減 keyring 的參考計數。當您呼叫 `aws_cryptosdk_session_destroy` 來銷毀工作階段時，將會釋出工作階段對 keyring 的參考。

```
// The session gets a reference to the keyring.
struct aws_cryptosdk_session *session =	
	aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_ENCRYPT, keyring);

// After you create a session with a keyring, release the reference to the keyring object.
aws_cryptosdk_keyring_release(keyring);
```

對於更複雜的任務，例如針對多個工作階段重複使用 keyring，或在 CMM 中指定演算法套件，您可能需要維護物件的獨立參考。如果是這樣，請勿立即呼叫釋出方法。而是除了銷毀工作階段之外，當您不再使用這些物件時，請釋出您的參考。

當您使用替代 CMMs 時，此參考計數技術也適用，例如[資料金鑰](data-key-caching.md)快取的快取 CMM。當您從快取和 keyring 建立快取 CMM 時，快取 CMM 會取得兩個物件的參考。除非您需要用於其他任務，否則您可以在快取 CMM 建立後立即釋出快取和 keyring 的獨立參考。然後，當您使用快取 CMM 建立工作階段時，您可以釋出快取 CMM 的參考。

請注意，您只需負責釋出您明確建立的物件參考。方法為您建立的物件，例如屬於快取 CMM 的預設 CMM，是由 方法管理。

```
/ Create the caching CMM from a cache and a keyring.
struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring(allocator, cache, kms_keyring, NULL, 60, AWS_TIMESTAMP_SECS);

// Release your references to the cache and the keyring.
aws_cryptosdk_materials_cache_release(cache);
aws_cryptosdk_keyring_release(kms_keyring);

// Create a session with the caching CMM.
struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm);

// Release your references to the caching CMM.
aws_cryptosdk_cmm_release(caching_cmm);

// ...

aws_cryptosdk_session_destroy(session);
```

# 適用於 C 的 AWS Encryption SDK 範例
<a name="c-examples"></a>

下列範例示範如何使用 適用於 C 的 AWS Encryption SDK 來加密和解密資料。

本節中的範例示範如何使用 2.0.*x* 版和更新版本 適用於 C 的 AWS Encryption SDK。如需使用舊版的範例，請參閱 GitHub 上 [aws-encryption-sdk-c 儲存庫](https://github.com/aws/aws-encryption-sdk-c/)的[版本](https://github.com/aws/aws-encryption-sdk-c/releases)清單。

當您安裝和建置 時 適用於 C 的 AWS Encryption SDK，這些和其他範例的原始碼會包含在 `examples`子目錄中，它們會編譯並內建到 `build`目錄中。您也可以在 GitHub 上 [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) 儲存庫[的範例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)子目錄中找到它們。

**Topics**
+ [加密和解密字串](#c-example-strings)

## 加密和解密字串
<a name="c-example-strings"></a>

下列範例示範如何使用 適用於 C 的 AWS Encryption SDK 來加密和解密字串。

此範例具有 [AWS KMS keyring](use-kms-keyring.md)，這是一種 keyring，使用 [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/) AWS KMS key 中的 來產生和加密資料金鑰。此範例包含以 C\$1\$1 撰寫的程式碼。 適用於 C 的 AWS Encryption SDK 要求 在使用 AWS KMS keyring AWS KMS 時 適用於 C\$1\$1 的 AWS SDK 呼叫 。如果您使用的 keyring 不與之互動 AWS KMS，例如原始 AES keyring、原始 RSA keyring 或不包含 AWS KMS keyring 的多 keyring， 適用於 C\$1\$1 的 AWS SDK 則不需要 。

如需建立 的說明 AWS KMS key，請參閱《 *AWS Key Management Service 開發人員指南*》中的[建立金鑰](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。如需在 AWS KMS keyring AWS KMS keys 中識別 的說明，請參閱 [在 AWS KMS keyring AWS KMS keys 中識別](use-kms-keyring.md#kms-keyring-id)。

**請參閱完整的程式碼範例**：[string.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/string.cpp)

**Topics**
+ [加密字串](#c-example-string-encrypt)
+ [解密字串](#c-example-string-decrypt)

### 加密字串
<a name="c-example-string-encrypt"></a>

此範例的第一部分使用具有 的 AWS KMS keyring AWS KMS key 來加密純文字字串。

步驟 1. 載入錯誤字串。  
在 C 或 C\$1\$1 程式碼中呼叫 `aws_cryptosdk_load_error_strings()`方法。它會載入對偵錯非常有用的錯誤資訊。  
您只需呼叫一次，例如在您的`main`方法中。  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

步驟 2：建構 keyring。  
建立用於加密的 AWS KMS keyring。此範例中的 keyring 設定為一個 AWS KMS key，但您可以設定具有多個 keyring 的 AWS KMS keyring AWS KMS keys，包括在 AWS KMS keys 不同的 AWS 區域 帳戶中。  
若要在 AWS KMS key 的加密 keyring 中識別 適用於 C 的 AWS Encryption SDK，請指定[金鑰 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 或[別名 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn)。在解密 Keyring 中，您必須使用金鑰 ARN。如需詳細資訊，請參閱[在 AWS KMS keyring AWS KMS keys 中識別](use-kms-keyring.md#kms-keyring-id)。  
[在 AWS KMS keyring AWS KMS keys 中識別](use-kms-keyring.md#kms-keyring-id)  
當您建立具有多個 的 keyring 時 AWS KMS keys，您可以指定 AWS KMS key 用於產生和加密純文字資料金鑰的 ，以及 AWS KMS keys 用於加密相同純文字資料金鑰的選用額外陣列。在此情況下，您只能指定產生器 AWS KMS key。  
執行此程式碼之前，請將範例金鑰 ARN 換成有效的金鑰 ARN。  

```
const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";    

struct aws_cryptosdk_keyring *kms_keyring = 
       Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
```

步驟 3：建立工作階段。  
使用分配器、模式列舉器和 keyring 來建立工作階段。  
每個工作階段需要模式：`AWS_CRYPTOSDK_ENCRYPT` 用來加密或 `AWS_CRYPTOSDK_DECRYPT` 用來解密。若要變更現有工作階段的模式，請使用 `aws_cryptosdk_session_reset` 方法。  
建立具有 keyring 的工作階段之後，您可以使用 SDK 提供的方法，將您的參考釋出給 keyring。工作階段會在其生命週期期間保留 keyring 物件的參考。當您銷毀工作階段時，會釋出 keyring 和工作階段物件的參考。此[參考計數](c-language-using.md#c-language-using-release)技術有助於避免記憶體流失，並避免在使用物件時釋出物件。  

```
struct aws_cryptosdk_session *session = 
       aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_ENCRYPT, kms_keyring);

/* When you add the keyring to the session, release the keyring object */
aws_cryptosdk_keyring_release(kms_keyring);
```

步驟 4：設定加密內容。  
[加密內容](concepts.md#encryption-context)是一種任意、非私密額外驗證資料。當您在加密時提供加密內容時， AWS Encryption SDK 密碼編譯會將加密內容繫結至加密文字，因此需要相同的加密內容來解密資料。使用加密內容是選用的，但我們建議使用它作為最佳實務。  
先建立包含加密內容字串的雜湊表格。  

```
/* Allocate a hash table for the encryption context */
int set_up_enc_ctx(struct aws_allocator *alloc, struct aws_hash_table *my_enc_ctx) 

// Create encryption context strings
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key1, "Example");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value1, "String");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key2, "Company");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value2, "MyCryptoCorp");

// Put the key-value pairs in the hash table
aws_hash_table_put(my_enc_ctx, enc_ctx_key1, (void *)enc_ctx_value1, &was_created)
aws_hash_table_put(my_enc_ctx, enc_ctx_key2, (void *)enc_ctx_value2, &was_created)
```
取得工作階段中加密內容的可變指標。然後，使用 `aws_cryptosdk_enc_ctx_clone` 函數來將加密內容複製到工作階段。將複本放在 `my_enc_ctx` 中，使得您可以在解密資料之後驗證其值。  
加密內容是工作階段的一部分，而非傳遞到工作階段處理函數的參數。這可保證將相同加密內容用於訊息的每個區段，即使呼叫了工作階段處理函數多次來加密整個訊息亦然。  

```
struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr_mut(session);

aws_cryptosdk_enc_ctx_clone(alloc, session_enc_ctx, my_enc_ctx)
```

步驟 5：加密字串。  
若要加密純文字字串，請使用 `aws_cryptosdk_session_process_full` 方法搭配加密模式的工作階段。此方法在 1.9.*x* 和 2.2.*x* AWS Encryption SDK 版中推出，專為非串流加密和解密而設計。若要處理串流資料，請在迴圈`aws_cryptosdk_session_process`中呼叫 。  
加密時，純文字欄位為輸入欄位；加密文字欄位為輸出欄位。當處理完成時，`ciphertext_output` 欄位會包含[加密的訊息](concepts.md#message)，包括實際加密文字、加密的資料金鑰和加密內容。您可以使用任何支援的程式設計語言 AWS Encryption SDK 的 來解密此加密訊息。  

```
/* Gets the length of the plaintext that the session processed */
size_t ciphertext_len_output;
if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session,
                                  ciphertext_output,
                                  ciphertext_buf_sz_output,
                                  &ciphertext_len_output,
                                  plaintext_input,
                                  plaintext_len_input)) {
    aws_cryptosdk_session_destroy(session);
    return 8;
}
```

步驟 6：清理工作階段。  
最後一個步驟會銷毀工作階段，包括對 CMM 和 keyring 的參考。  
如果您偏好使用相同的 keyring 和 CMM 來解密字串，或加密或解密其他訊息，而不是銷毀工作階段。若要將工作階段用於解密，請使用 `aws_cryptosdk_session_reset` 方法來將模式變更為 `AWS_CRYPTOSDK_DECRYPT`。

### 解密字串
<a name="c-example-string-decrypt"></a>

此範例的第二個部分會將包含原始字串之加密文字的加密訊息解密。

步驟 1：載入錯誤字串。  
在 C 或 C\$1\$1 程式碼中呼叫 `aws_cryptosdk_load_error_strings()`方法。它會載入對偵錯非常有用的錯誤資訊。  
您只需呼叫一次，例如在您的`main`方法中。  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

步驟 2：建構 keyring。  
當您解密資料時 AWS KMS，您會傳入加密 API 傳回的加密[訊息](concepts.md#message)。[Decrypt API](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 不會將 AWS KMS key 做為輸入。反之， AWS KMS 會使用相同的 AWS KMS key 來解密其用來加密的加密文字。不過， AWS Encryption SDK 可讓您在加密和解密 AWS KMS keys 時，使用 指定 AWS KMS keyring。  
解密時，您可以使用只 AWS KMS keys 想要用來解密加密訊息的 來設定 keyring。例如，您可能想要使用組織中特定角色 AWS KMS key 所使用的 來建立 keyring。除非 AWS Encryption SDK 出現在解密 keyring 中， AWS KMS key 否則 永遠不會使用 。如果 SDK 無法使用您提供的 keyring AWS KMS keys 中的 來解密加密的資料金鑰，因為 keyring AWS KMS keys 中沒有任何 用於加密任何資料金鑰，或因為發起人沒有在 keyring AWS KMS keys 中使用 的許可，解密呼叫會失敗。  
當您 AWS KMS key 為解密 keyring 指定 時，您必須使用其[金鑰 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN)。[別名 ARNs](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn) 僅允許在加密 keyring 中。如需在 AWS KMS keyring AWS KMS keys 中識別 的說明，請參閱 [在 AWS KMS keyring AWS KMS keys 中識別](use-kms-keyring.md#kms-keyring-id)。  
在此範例中，我們會指定使用 AWS KMS key 用來加密字串的相同 設定的 keyring。執行此程式碼之前，請將範例金鑰 ARN 換成有效的金鑰 ARN。  

```
const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"    

struct aws_cryptosdk_keyring *kms_keyring =
        Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
```

步驟 3：建立工作階段。  
使用分配器和 keyring 來建立工作階段。若要設定用於解密的工作階段，請使用 `AWS_CRYPTOSDK_DECRYPT` 模式設定工作階段。  
建立具有 keyring 的工作階段之後，您可以使用 SDK 提供的方法，將您的參考釋出給 keyring。工作階段會在其生命週期期間保留對 keyring 物件的參考，當您銷毀工作階段時，工作階段和 keyring 都會釋出。此參考計數技術有助於避免記憶體流失，並避免在使用物件時釋出物件。  

```
struct aws_cryptosdk_session *session =	
	aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_DECRYPT, kms_keyring);

/* When you add the keyring to the session, release the keyring object */
aws_cryptosdk_keyring_release(kms_keyring);
```

步驟 4：將字串解密。  
若要解密字串，請使用 `aws_cryptosdk_session_process_full` 方法搭配設定用於解密的工作階段。此方法在 1.9.*x* 和 2.2.*x* AWS Encryption SDK 版中推出，專為非串流加密和解密而設計。若要處理串流資料，請在迴圈`aws_cryptosdk_session_process`中呼叫 。  
解密時，加密文字欄位為輸入欄位，而純文字欄位為輸出欄位。`ciphertext_input` 欄位會保存加密方法傳回的[加密的訊息](message-format.md)。當處理完成時，`plaintext_output` 欄位會包含純文字 (解密的) 字串。  

```
size_t plaintext_len_output;

if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session,
                                  plaintext_output,
                                  plaintext_buf_sz_output,
                                  &plaintext_len_output,
                                  ciphertext_input,
                                  ciphertext_len_input)) {
    aws_cryptosdk_session_destroy(session);
    return 13;
}
```

步驟 5：驗證加密內容。  
請確定實際加密內容 — 用來解密訊息的內容 — 包含您在加密訊息時提供的加密內容。實際加密內容可能包含額外配對，因為[密碼編譯資料管理員](concepts.md#crypt-materials-manager) (CMM) 可以在加密訊息之前，將配對新增到提供的加密內容。  
在 中 適用於 C 的 AWS Encryption SDK，您不需要在解密時提供加密內容，因為加密內容包含在 SDK 傳回的加密訊息中。但是，在它傳回純文字訊息之前，您的解密函數應該驗證提供的解密內容中的所有配對會出現在解密訊息所用的加密內容中。  
首先，取得工作階段中雜湊表格的唯讀指標。此雜湊表格中包含解密訊息所用的加密內容。  

```
const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);
```
然後循環回應您在加密時複製的 `my_enc_ctx` 雜湊表格中的加密內容。驗證用來解密的 `my_enc_ctx` 雜湊表格中的每個配對顯示在解密所用的 `session_enc_ctx` 雜湊表格中。如果有任何金鑰遺漏，或是該金鑰有不同的值，便停止處理並寫入錯誤訊息。  

```
for (struct aws_hash_iter iter = aws_hash_iter_begin(my_enc_ctx); !aws_hash_iter_done(&iter);
      aws_hash_iter_next(&iter)) {
     struct aws_hash_element *session_enc_ctx_kv_pair;
     aws_hash_table_find(session_enc_ctx, iter.element.key, &session_enc_ctx_kv_pair)

    if (!session_enc_ctx_kv_pair ||
        !aws_string_eq(
            (struct aws_string *)iter.element.value, (struct aws_string *)session_enc_ctx_kv_pair->value)) {
        fprintf(stderr, "Wrong encryption context!\n");
        abort();
    }
}
```

步驟 6：清理工作階段。  
驗證加密內容之後，您可以銷毀或重複使用工作階段。如果您需要重新設定工作階段，請使用 `aws_cryptosdk_session_reset`方法。  

```
aws_cryptosdk_session_destroy(session);
```