

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS Encryption SDK for C 例
<a name="c-examples"></a>

次の例は、 AWS Encryption SDK for C を使用してデータを暗号化および復号する方法を示しています。

このセクションの例では、 AWS Encryption SDK for Cのバージョン 2.0.x 以降の使用方法について説明します。　 前バージョンを使用する例については、GitHub の [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) リポジトリの[リリース](https://github.com/aws/aws-encryption-sdk-c/releases)リストで使用中のリリースを検索してください。

をインストールしてビルドすると AWS Encryption SDK for C、これらの例やその他の例のソースコードが `examples` サブディレクトリに含まれ、コンパイルされて `build` ディレクトリに組み込まれます。GitHub の [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) リポジトリの [examples](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples) サブディレクトリで検索することもできます。

**Topics**
+ [文字列の暗号化と復号](#c-example-strings)

## 文字列の暗号化と復号
<a name="c-example-strings"></a>

次の例は、 を使用して文字列を AWS Encryption SDK for C 暗号化および復号する方法を示しています。

この例では、 AWS KMS key [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/) の を使用してデータ[AWS KMS キー](use-kms-keyring.md)を生成および暗号化するキーリングの一種である キーリングを使用しています。この例には C\$1\$1 で記述されたコードが含まれています。　 AWS Encryption SDK for C では AWS SDK for C\$1\$1 、 AWS KMS キーリングを使用する AWS KMS ときに を呼び出す必要があります。raw AES キーリング AWS KMS、raw RSA キーリング、または キーリングを含まないマルチキーリングなど、 とやり取りしない AWS KMS キーリングを使用している場合、 AWS SDK for C\$1\$1 は必要ありません。

の作成については AWS KMS key、「 *AWS Key Management Service デベロッパーガイド*」の[「キーの作成](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)」を参照してください。 AWS KMS キーリング AWS KMS keys で を識別する方法については、「」を参照してください[AWS KMS キーリング 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 キーリングと キーリング AWS KMS key を使用してプレーンテキスト文字列を暗号化します。

ステップ 1. エラー文字列をロード  
C コードまたは C\$1\$1 コードで `aws_cryptosdk_load_error_strings()` メソッドを呼び出します。デバッグに非常に役立つエラー情報をロードします。  
`main` メソッド内でなど、1 回だけ呼び出す必要があります。  

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

ステップ 2: キーリングを作成します。  
暗号化用の AWS KMS キーリングを作成します。この例のキーリングは 1 つで設定されていますが AWS KMS key、 AWS KMS keys 異なるアカウント AWS リージョン や異なるアカウントを含む AWS KMS keys複数の で AWS KMS キーリングを設定できます。  
 AWS KMS key の暗号化キーリングで を識別するには AWS Encryption SDK for C、[キー 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) を指定します。復号キーリングでは、キー ARN を使用する必要があります。詳細については、「[AWS KMS キーリング AWS KMS keys での の識別](use-kms-keyring.md#kms-keyring-id)」を参照してください。  
[AWS KMS キーリング AWS KMS keys での の識別](use-kms-keyring.md#kms-keyring-id)  
複数の を使用してキーリングを作成するときは 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: セッションを作成します。  
アロケーター、モードの列挙子、キーリングを使用してセッションを作成します。  
各セッションは、`AWS_CRYPTOSDK_ENCRYPT` モード (暗号化) または `AWS_CRYPTOSDK_DECRYPT` モード (復号) にする必要があります。既存のセッションのモードを変更するには、`aws_cryptosdk_session_reset` メソッドを使用します。  
キーリングを使用してセッションを作成したら、SDK が提供する機能を使用してキーリングへの参照を解放できます。セッションは、その有効期間中、キーリングオブジェクトへの参照を保持します。セッションを破棄すると、キーリングオブジェクトやセッションオブジェクトへの参照が解放されます。この[参照カウント](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` メソッドを使用します。このメソッドは、 AWS Encryption SDK バージョン 1.9.*x* および 2.2.*x* で導入され、非ストリーミング暗号化と復号化用に設計されています。ストリーミングデータを処理するには、ループで `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 とキーリングへの参照を含むセッションを破棄します。  
必要に応じて、セッションを破棄せずに、同じキーリングと CMM でセッションを再利用し、文字列の復号や、他のメッセージの暗号化または復号を行うことができます。復号のセッションを使用するには、`aws_cryptosdk_session_reset` メソッドを使用して、モードを `AWS_CRYPTOSDK_DECRYPT` に変更します。

### 文字列の復号
<a name="c-example-string-decrypt"></a>

この例の 2 番目の部分では、元の文字列の暗号化テキストを含む暗号化されたメッセージを復号します。

ステップ 1: エラー文字列をロード  
C コードまたは C\$1\$1 コードで `aws_cryptosdk_load_error_strings()` メソッドを呼び出します。デバッグに非常に役立つエラー情報をロードします。  
`main` メソッド内でなど、1 回だけ呼び出す必要があります。  

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

ステップ 2: キーリングを作成します。  
でデータを復号すると 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 キーリングを指定できます。  
復号では、暗号化されたメッセージの復号 AWS KMS keys に使用する のみを使用してキーリングを設定できます。たとえば、組織内の特定のロール AWS KMS key で使用される のみを使用してキーリングを作成するとします。復号キーリングに表示され AWS KMS key ない限り、 AWS Encryption SDK は を使用しません。指定したキーリング AWS KMS keys で を使用して暗号化されたデータキーを SDK が復号できない場合、キーリング AWS KMS keys の がデータキーの暗号化に使用されなかったか、呼び出し元にキーリング AWS KMS keys の を使用して復号するアクセス許可がないため、復号呼び出しは失敗します。  
復号キーリング AWS KMS key に を指定する場合は、その[キー 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) は、暗号化キーリングでのみ許可されます。 AWS KMS キーリング AWS KMS keys で を識別する方法については、「」を参照してください[AWS KMS キーリング AWS KMS keys での の識別](use-kms-keyring.md#kms-keyring-id)。  
この例では、文字列の暗号化 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: セッションを作成します。  
アロケーターとキーリングを使用してセッションを作成します。セッションを復号用に設定するには、セッションを `AWS_CRYPTOSDK_DECRYPT` モードに設定します。  
キーリングを使用してセッションを作成したら、SDK が提供する機能を使用してキーリングへの参照を解放できます。セッションは、その有効期間中、キーリングオブジェクトへの参照を保持します。セッションを破棄すると、セッションとキーリングの両方が解放されます。この参照カウント方式は、メモリリークを防ぎ、オブジェクトが使用中に解放されないようにするために役立ちます。  

```
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` メソッドを使用します。 AWS Encryption SDK バージョン 1.9.*x* および 2.2.*x* で導入されたこのメソッドは、非ストリーミングの暗号化および復号化のために設計されています。ストリーミングデータを処理するには、ループで `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) によって、メッセージの暗号化前に指定した暗号化コンテキストにペアが追加される場合があるため、実際の暗号化コンテキストには、追加のペアが含まれる場合があります。  
では AWS Encryption SDK for C、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);
```