

# API リクエストに対する AWS Signature Version 4
<a name="reference_sigv"></a>

**重要**  
AWS SDK (「[サンプルコードとライブラリ](https://aws.amazon.com/developer/)」を参照) または AWS Command Line Interface (AWS CLI) ツールを使用して API リクエストを AWS に送信する場合、SDK および CLI クライアントが指定したアクセスキーを使用してリクエストを認証するため、署名プロセスをスキップできます。正当な理由がない限り、常に SDK または CLI を使用することをお勧めします。  
複数の署名バージョンをサポートするリージョンでは、リクエストに手動で署名する場合、使用する署名バージョンを指定する必要があります。マルチリージョンアクセスポイントにリクエストを送信すると、SDK と CLI は Signature Version 4A の使用に自動的に切り替えます。追加の設定は不要です。

リクエストで送信する認証情報には、署名が含まれている必要があります。AWSSignature Version 4 (SigV4) は、AWS API リクエストに認証情報を追加するための AWS 署名プロトコルです。

API リクエストの署名には、シークレットアクセスキーを使用しません。そうではなく、SigV4 署名プロセスを使用します。リクエストを署名するには、以下の手順を実行します。

1. リクエストの詳しい情報に基づいて正規リクエストを作成します。

1. 自分の AWS 認証情報を使用して署名を計算します。

1. 求めた署名を認可ヘッダーとしてリクエストに追加します。

AWS は、このプロセスをレプリケートして署名を検証し、検証結果に応じてアクセスを許可または拒否します。

Symmetric SigV4 では、特定の日に 1 つの AWS リージョンの 1 つの AWS サービスに限定されたキーを取得する必要があります。これにより、キーと計算された署名はリージョンごとに異なるため、どのリージョンにリクエストを送るのかを事前に把握しておく必要があります。

非対称署名バージョン 4 (SigV4a ) は、新しいアルゴリズムによる署名と、複数の AWS リージョンで検証可能な個々の署名の生成をサポートする拡張機能です。SigV4a を使用すると、複数のリージョンのリクエストに署名し、リージョン間でシームレスなルーティングとフェイルオーバーを行うことができます。AWS SDK または AWS CLI を使用して、マルチリージョン署名を必要とする機能を呼び出すと、署名タイプが自動的に SigV4a を使用するように変更されます。詳細については、「[AWS SigV4a の仕組み](#how-sigv4a-works)」を参照してください。

## AWS SigV4 の仕組み
<a name="how-aws-signing-works"></a>

次の手順では、SigV4 を使用して署名を計算する一般的なプロセスについて説明します。

1. **署名する文字列**はリクエストのタイプによって異なります。例えば、認証に HTTP Authorization ヘッダーまたはクエリパラメータを使用する場合、リクエスト要素を組み合わせて、署名文字列を作成します。HTTP POST リクエストでは、リクエスト内の `POST` ポリシーは、署名する文字列です。

1. **署名キー**は、一続きの計算で求められ、各ステップの結果が次の計算に送られます。最後の手順は署名キーです。

1. AWS サービスが認証されたリクエストを受け取ると、リクエストに含まれる認証情報を使用して**署名**が再作成されます。署名が一致すると、サービスはリクエストを処理します。それ以外の場合、リクエストを拒否します。

詳細については、「[AWS API リクエスト署名の要素](reference_sigv-signing-elements.md)」を参照してください。

## AWS SigV4a の仕組み
<a name="how-sigv4a-works"></a>

SigV4a は、公開鍵暗号方式に基づく非対称署名を使用します。SigV4a は、SigV4 と同様のスコープ認証情報導出プロセスを実行します。ただし、Sigv4a は同じキーを使用してすべてのリクエストに署名します。日付、サービス、リージョンに基づいて個別の署名キーを取得する必要はありません。[楕円曲線デジタル署名アルゴリズム](https://csrc.nist.gov/glossary/term/ecdsa) (ECDSA) キーペアは、既存の AWS シークレットアクセスキーから取得できます。

システムは非対称暗号化を使用してマルチリージョン署名を検証するため、AWS はパブリックキーのみを保存する必要があります。パブリックキーはシークレットではなく、リクエストの署名には使用できません。非対称署名は、Amazon S3 マルチリージョン アクセス ポイントなどのマルチリージョン API リクエストに必要です。

次の手順では、SigV4a を使用して署名を計算する一般的なプロセスについて説明します。

1. **署名する文字列**はリクエストのタイプによって異なります。例えば、認証に HTTP Authorization ヘッダーまたはクエリパラメータを使用する場合、リクエスト要素を組み合わせて、署名文字列を作成します。HTTP POST リクエストでは、リクエスト内の `POST` ポリシーは、署名する文字列です。

1. **署名キー**は、AWS のシークレットアクセスキーから一連の計算によって求められ、各ステップの結果が次の計算に送られます。最後のステップでは、キーペアを生成します。

1. AWS サービスが Sigv4a で署名されたリクエストを受信すると、 AWS はキーペアのパブリック半分のみを使用して署名を検証します。署名が有効な場合、リクエストは認証され、サービスはリクエストを処理します。無効な署名を持つリクエストは拒否されます。

マルチリージョン API リクエストの SigV4a の詳細については、GitHub の「[sigv4a-signing-examples](https://github.com/aws-samples/sigv4a-signing-examples)」プロジェクトを参照してください。

## リクエストに署名するタイミング
<a name="when-do-you-need-to-sign"></a>

AWS に API リクエストを送信するためのカスタムコードを記述するときは、リクエストに署名するためのコードを含める必要があります。カスタムコードを書く理由には、以下のような場合が考えられます。
+ AWS SDK がないプログラミング言語を使用しているためです。
+ AWS にリクエストを送る方法を完全に管理する必要がある場合。

API リクエストは AWS SigV4 でアクセスを認証しますが、AWS SDK と AWS CLI はユーザーが指定したアクセスキーを使用してリクエストを認証します。AWS SDK と AWS CLI による認証の詳細については、「[追加リソース](#reference_aws-signing-resources)」を参照してください。

## リクエストに署名する理由
<a name="why-requests-are-signed"></a>

署名プロセスは、次のような点でリクエストのセキュリティ確保に役立ちます。
+ **リクエスタの ID の確認**

  認証されたリクエストには、アクセスキー (アクセスキー ID、シークレットアクセスキー) を使用して作成した署名が必要です。一時的なセキュリティ認証情報を使用している場合、署名の計算にはセキュリティトークンも必要です。詳細については、「[AWS security credentials programmatic access](security-creds-programmatic-access.md)」(セキュリティ認証情報のプログラムによるアクセス) を参照してください。
+ **送信中のデータの保護**

  送信中のリクエストの改ざんを防ぐために、一部のリクエスト要素からリクエストのハッシュ (ダイジェスト) を計算し、得られたハッシュ値をリクエストの一部として含めます。AWS のサービス がリクエストを受け取ると、同じ情報を使用してハッシュを計算し、リクエストに含まれているハッシュ値と比較します。ハッシュ値が一致しない場合、AWS はそのリクエストを拒否します。
+ **潜在的なリプレイ攻撃の防止**

  多くの場合、リクエストは、リクエストのタイムスタンプの 5 分以内に AWS に到達する必要があります。その条件を満たさない場合、AWS はリクエストを拒否します。

AWS SigV4 は、HTTP 認可ヘッダーに表現することも、URL にクエリ文字列として表現することもできます。詳細については、「[認証方法](reference_sigv-authentication-methods.md)」を参照してください。

## 追加リソース
<a name="reference_aws-signing-resources"></a>
+ さまざまなサービスの SigV4 署名プロセスの詳細については、「[リクエスト署名の例](reference_sigv-examples.md)」を参照してください。
+ AWS CLI でプログラマティックにアクセスできるように認証情報を設定するには、「AWS コマンドラインインターフェイスユーザーガイド」の「[認証とアクセス認証情報](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html)」を参照してください。
+ AWS SDK には、AWS API リクエストに署名する方法を示す GitHub のソースコードが含まれています。コードの例については、「[AWS サンプルリポジトリ内のプロジェクト例](reference_sigv-examples.md#signature-v4-examples-sdk)」を参照してください。
  + AWS SDK for .NET – [AWS4Signer.cs](https://github.com/aws/aws-sdk-net/blob/master/sdk/src/Core/Amazon.Runtime/Internal/Auth/AWS4Signer.cs)
  + AWS SDK for C\$1\$1 – [AWSAuthV4Signer.cpp](https://github.com/aws/aws-sdk-cpp/blob/main/src/aws-cpp-sdk-core/source/auth/signer/AWSAuthV4Signer.cpp)
  + AWS SDK for Go – [sigv4.go](https://github.com/aws/smithy-go/blob/a4c9efcda6aa54c75d1a130d1320a2709eebf51d/aws-http-auth/sigv4/sigv4.go)
  + AWS SDK for Java – [BaseAws4Signer.java](https://github.com/aws/aws-sdk-java-v2/blob/master/core/auth/src/main/java/software/amazon/awssdk/auth/signer/internal/BaseAws4Signer.java)
  + AWS SDK for JavaScript – [signature-v4](https://github.com/smithy-lang/smithy-typescript/tree/main/packages/signature-v4)
  + AWS SDK for PHP – [SignatureV4.php](https://github.com/aws/aws-sdk-php/blob/master/src/Signature/SignatureV4.php)
  + AWS SDK for Python (Boto) – [signers.py](https://github.com/boto/botocore/blob/develop/botocore/signers.py)
  + AWS SDK for Ruby – [signer.rb](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sigv4/lib/aws-sigv4/signer.rb)

# AWS API リクエスト署名の要素
<a name="reference_sigv-signing-elements"></a>

**重要**  
AWS SDK または CLI を使用していない限り、リクエストの認証情報を提供する署名を計算するコードを記述する必要があります。AWS Signature Version 4 での署名計算は複雑な作業になる場合があるため、可能な限り AWS SDK または CLI を使用することをお勧めします。

Signature Version 4 の署名を使用する各 HTTP/HTTPS リクエストには、これらの要素を含める必要があります。

**Topics**
+ [エンドポイント仕様](#endpoint-specification)
+ [Action](#action)
+ [アクションパラメータ](#parameters)
+ [日付](#date)
+ [認証情報](#authentication)

## エンドポイント仕様
<a name="endpoint-specification"></a>

リクエストの送信先となるエンドポイントの DNS 名を指定します。この名前には通常、サービスコードとリージョンが含まれます。たとえば、`us-east-1` リージョンの Amazon DynamoDB のエンドポイントは `dynamodb.us-east-1.amazonaws.com` です。

HTTP/1.1 リクエストには、`Host` ヘッダーを含める必要があります。HTTP/2 リクエストの場合は、`:authority` ヘッダー、または `Host` ヘッダーを含められます。HTTP/2 仕様にのみ準拠するには、`:authority` ヘッダーのみ使用します。すべてのサービスが HTTP/2 リクエストをサポートしているわけではありません。

各サービスでサポートされているエンドポイントについては、「AWS 全般のリファレンス」の「[サービスエンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html)」を参照してください。

## Action
<a name="action"></a>

サービスの API アクションを指定します。たとえば、DynamoDB `CreateTable` アクションや Amazon EC2 `DescribeInstances` アクションなどです。

各サービスでサポートされているアクションについては、「[サービス認可リファレンス](https://docs.aws.amazon.com//service-authorization/latest/reference/reference.html)」を参照してください。

## アクションパラメータ
<a name="parameters"></a>

リクエストで指定されたアクションのパラメータを指定します。各 AWS API アクションには、必須およびオプションのパラメータのセットがあります。API バージョンは通常、必須パラメータです。

API アクションでサポートされるパラメータについては、サービスの「API リファレンス」を参照してください。

## 日付
<a name="date"></a>

リクエストの日付と時刻を指定します。日付と時刻をリクエストに含めると、サードパーティーによるリクエストの傍受や再送信の防止に役立ちます。認証情報スコープで指定した日付は、リクエストの日付と一致する必要があります。

タイムスタンプは UTC で、*YYYYMMDD*T*HHMMSS*Z の ISO 8601 形式を使用する必要があります。例えば、`20220830T123600Z`。タイムスタンプにミリ秒を含めないでください。

`date` または `x-amz-date` ヘッダーを使用するか、`x-amz-date` をクエリパラメータとして含めることができます。`x-amz-date` ヘッダーが見つからない場合は、`date` ヘッダーを探します。

## 認証情報
<a name="authentication"></a>

送信する各リクエストには、次の情報を含める必要があります。AWS はこの情報を使用してリクエストの有効性と信頼性を確保しています。
+ アルゴリズム – 署名プロセスの一部として使用しているアルゴリズム。
  + SigV4 — `HMAC-SHA256` ハッシュアルゴリズムで Signature Version 4 を指定する場合に `AWS4-HMAC-SHA256` を使用します。
  + SigV4a – `ECDSA-P256-SHA-256` ハッシュアルゴリズムを指定するために `AWS4-ECDSA-P256-SHA256` を使用します
+ 認証情報 – アクセスキー ID と認証情報スコープのコンポーネントを連結して形成される文字列。
  + SigV4 – 認証情報スコープには、アクセスキー ID、*YYYYMMDD* 形式の日付、リージョンコード、サービスコード、およびスラッシュ (/) で区切った `aws4_request` 終了文字列が含まれます。リージョンコード、サービスコード、および終了文字列には、小文字を使用する必要があります。

    ```
    AKIAIOSFODNN7EXAMPLE/YYYYMMDD/region/service/aws4_request
    ```
  + SigV4a – 認証情報スコープには、YYYYMMDD 形式の日付、サービス名、およびスラッシュ (/) で区切った `aws4_request` 終了文字列が含まれます。このリージョンは別のヘッダー `X-Amz-Region-Set` でカバーされているため、認証情報スコープにはこのリージョンが含まれないことに注意してください。

    ```
    AKIAIOSFODNN7EXAMPLE/YYYYMMDD/service/aws4_request
    ```
+ 署名付きヘッダー — 署名に含める HTTP ヘッダーを、セミコロン (;) で区切ります。例えば、`host;x-amz-date`。

  SigV4a の場合、リクエストが有効なリージョンセットを指定するリージョンセットヘッダーを含める必要があります。ヘッダー `X-Amz-Region-Set` はカンマ区切り値のリストとして指定されます。次の例は、us-east-1 リージョンと us-west-1 リージョンの両方でリクエストを行うことを許可するリージョンヘッダーを示しています。

  ```
  X-Amz-Region-Set=us-east-1,us-west-1
  ```

  リージョンでワイルドカード (\$1) を使用して、複数のリージョンを指定できます。次の例では、ヘッダーを使用して、us-west-1 と us-west-2 の両方でリクエストを行うことができます。

  ```
  X-Amz-Region-Set=us-west-*
  ```
+ 署名 — 計算された署名を表す 16 進エンコードされた文字列。`Algorithm` パラメータで指定したアルゴリズムを使用して署名を計算する必要があります。

詳細については、[認証方法](reference_sigv-authentication-methods.md) を参照してください。

# 認証方法
<a name="reference_sigv-authentication-methods"></a>

**重要**  
AWS SDK または CLI を使用していない限り、リクエストの認証情報を提供する署名を計算するコードを記述する必要があります。AWS Signature Version 4 での署名計算は複雑な作業になる場合があるため、可能な限り AWS SDK または CLI を使用することをお勧めします。

認証情報は、次のいずれかの方法で表現できます。

## HTTP 認可ヘッダー
<a name="aws-signing-authentication-methods-http"></a>

HTTP `Authorization` ヘッダーはリクエストを認証する最も一般的な方法です。すべての REST API 操作 (`POST` リクエストを使用したブラウザベースのアップロードを除く) には、このヘッダーが必要です。

次の例は、SigV4 および SigV4a の `Authorization` ヘッダー値を示しています。この例では、読みやすいように改行が追加されています。コードでは、ヘッダーは連続した文字列である必要があります。アルゴリズムと認証情報の間にカンマはありませんが、他の要素はカンマで区切る必要があります。

**Example SigV4**  

```
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, 
SignedHeaders=host;range;x-amz-date, 
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
```

**Example SigV4a**  

```
Authorization: AWS4-ECDSA-P256-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20130524/s3/aws4_request, 
SignedHeaders=host;range;x-amz-date;x-amz-region-set,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
```

次の表では、前述の例にある認可ヘッダー値のさまざまなコンポーネントについて説明しています。


| コンポーネント | 説明 | 
| --- | --- | 
|  Authorization  | 署名の計算に使用されたアルゴリズム。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-authentication-methods.html)  | 
|  [認証情報]  |  アクセスキー ID とスコープ情報。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) <date> 値は YYYYMMDD 形式で指定されます。Amazon S3 にリクエストを送信するときの <aws-service> 値は s3 です。  | 
|  SignedHeaders  |   Signature の計算に使用したリクエストヘッダーをセミコロンで区切ったリスト。リストにはヘッダー名のみが含まれており、ヘッダー名は小文字である必要があります。例: `host;range;x-amz-date` SigV4a の場合、リクエストが有効なリージョンセットを指定するリージョンセットヘッダーを含める必要があります。ヘッダー X-Amz-Region-Set は、カンマ区切り値のリストとして指定されます。  | 
|  Signature  |  64 個の小文字の 16 進数文字で表現される 256 ビットの署名。以下に例を示します。`fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024` 署名計算は、ペイロードの転送に選択したオプションによって異なります。  | 

## クエリ文字列パラメータ
<a name="aws-signing-authentication-methods-query"></a>

クエリ文字列を使用すると、リクエスト全体を URL で表現できます。この場合、クエリパラメータを使用して、認証情報を含むリクエスト情報を提供します。リクエスト署名は URL の一部であるため、この種類の URL は署名付き URL と呼ばれることがよくあります。署名付き URL を使用して、クリック可能なリンクを HTML に埋め込むことができます。このリンクは最大 7 日間有効です。詳細については、「Amazon S3 API リファレンス」の「[リクエストの認証: クエリパラメータの使用 (AWS Signature Version 4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)」を参照してください。

次の例は、SigV4 および SigV4a の署名付き URLs を示しています。この例では、読みやすいように改行が追加されています。

**Example SigV4**  

```
https://s3.amazonaws.com/amzn-s3-demo-bucket/test.txt ?
X-Amz-Algorithm=AWS4-HMAC-SHA256 &
X-Amz-Credential=<your-access-key-id>/20130721/<region>/s3/aws4_request &
X-Amz-Date=20130721T201207Z &
X-Amz-Expires=86400 &
X-Amz-SignedHeaders=host &X-Amz-Signature=<signature-value>
```

**Example SigV4a**  

```
http://s3.amazonaws.com/amzn-s3-demo-bucket/test.txt ?
X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256 &
X-Amz-Credential=<your-access-key-id>/20240721/s3/aws4_request &
X-amz-Region-Set=<regionset> &
X-Amz-Date=20240721T201207Z &
X-Amz-Expires=86400 &
X-Amz-SignedHeaders=host;x-amz-region-set &
X-Amz-Signature=<signature-value>
```

**注記**  
URL 内の `X-Amz-Credential` 値には、読みやすさのためにのみ挿入された「/」文字が表示されています。実際には、%2F としてエンコードする必要があります。例えば、次のようになります。  
`&X-Amz-Credential=<your-access-key-id>%2F20130721%2Fus-east-1%2Fs3%2Faws4_request`

次の表では、認証情報を提供する URL 内のクエリパラメータについて説明します。


| クエリ文字列パラメータ名 | 説明 | 
| --- | --- | 
|  X-Amz-Algorithm  |  AWS 署名のバージョンと署名の計算に使用したアルゴリズム。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-authentication-methods.html)  | 
|  X-Amz-Credential  |  このパラメータは、アクセスキー ID の他に、署名が有効なスコープも指定します。この値は、次のセクションで説明する署名計算で使用するスコープと一致する必要があります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) AWS リージョン文字列のリストについては、「AWS 全般のリファレンス」の「[リージョンのエンドポイント](https://docs.aws.amazon.com//general/latest/gr/rande.html#regional-endpoints)」を参照してください。  | 
|  X-Amz-Region-Set  |  リクエストが有効になる一連のリージョン。ヘッダー x-amz-region-set は、カンマ区切り値のリストとして指定されます。  | 
|  X-Amz-Date  |  日付と時刻の形式は ISO 8601 規格に準拠している必要があるため、`yyyyMMddTHHmmssZ` 形式でフォーマットする必要があります。例えば、日付と時刻が「08/01/2016 15:32:41.982-700」の場合、まず UTC (協定世界時) に変換してから「20160801T223241Z」として送信する必要があります。  | 
|  X-Amz-Expires  |  生成された署名付き URL が有効な期間を秒単位で指定します。例えば、86400 (24 時間) と指定します。この値は整数です。設定できる最小値は 1 で、最大値は 604800 (7 日間) です。署名計算に使用する署名キーは最大 7 日間有効であるため、署名付き URL は最大 7 日間有効です。  | 
|  X-Amz-SignedHeaders  |  署名の計算に使用したヘッダーを一覧表示します。署名計算には次のヘッダーが必要です。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) セキュリティの強化のために、リクエストに含める予定のすべてのリクエストヘッダーに署名する必要があります。  | 
|  X-Amz-Signature  |  リクエストを認証するための署名を指定します。この署名は、サービスが計算する署名と一致する必要があります。一致しない場合、サービスはリクエストを拒否します。例: `733255ef022bec3f2a8701cd61d4b371f3f28c9f193a1f02279211d48d5193d7` 署名計算については、次のセクションで説明します。  | 
|  X-Amz-Security-Token  |  STS サービスから取得した認証情報を使用する場合のオプションの認証情報パラメータ。  | 

# 署名付き AWS API リクエストを作成する
<a name="reference_sigv-create-signed-request"></a>

**重要**  
AWS SDK (「[サンプルコードとライブラリ](https://aws.amazon.com/developer/)」を参照) または AWS Command Line Interface (AWS CLI) ツールを使用して API リクエストを AWS に送信する場合、SDK および CLI クライアントが指定したアクセスキーを使用してリクエストを認証するため、このセクションをスキップできます。正当な理由がない限り、常に SDK または CLI を使用することをお勧めします。  
複数の署名バージョンをサポートするリージョンでは、リクエストに手動で署名する場合、使用する署名バージョンを指定する必要があります。マルチリージョンアクセスポイントにリクエストを送信すると、SDK と CLI は Signature Version 4A の使用に自動的に切り替えます。追加の設定は不要です。

AWS SigV4 署名プロトコルを使用して、AWS API リクエストを署名付きで作成できます。

1. リクエストの詳しい情報に基づいて正規リクエストを作成します。

1. 自分の AWS 認証情報を使用して署名を計算します。

1. 求めた署名を認可ヘッダーとしてリクエストに追加します。

AWS は、このプロセスをレプリケートして署名を検証し、検証結果に応じてアクセスを許可または拒否します。

AWS SigV4 を使用して API リクエストに署名する方法を確認する場合は、「[リクエスト署名の例](reference_sigv-examples.md)」を参照してください。

次の表は、署名付きリクエストの作成プロセスで使用される関数を示しています。これらの関数のコードを実装する必要があります。詳細については、「[AWS SDK のサンプルコード](reference_sigv.md#reference_aws-signing-resources)」を参照してください。


| 関数 | 説明 | 
| --- | --- | 
|  `Lowercase()`  |  文字列を小文字に変換します。  | 
|  `Hex()`  |  16 進数の小文字エンコード。  | 
|  `SHA256Hash()`  |  セキュアハッシュアルゴリズム (SHA) 暗号化ハッシュ関数。  | 
|  `HMAC-SHA256()`  |  指定した署名キーで SHA256 アルゴリズムを使用して HMAC を計算します。これは SigV4 で署名するときの最終署名です。  | 
|  `ECDSA-Sign`  |  パブリック/プライベートキー暗号化に基づく非対称署名を使用して計算された楕円曲線デジタル署名アルゴリズム (ECDSA) 署名。  | 
|  `KDF(K, Label, Context, L)`  |  [NIST SP800–108r1](https://doi.org/10.6028/NIST.SP.800-108r1-upd1) で定義されているように、PRF 関数 HMAC-SHA256 を使用するカウンターモードの NIST SP800-108 KDF。  | 
|  `Oct2Int(byte[ ])`  |  ANSI X9.62 で説明されているオクテットから整数への関数。  | 
|  `Trim()`  |  先頭または末尾の空白をすべて削除します。  | 
|  `UriEncode()`  |  すべてのバイトが URI でエンコードされます。UriEncode() は、以下のルールを適用する必要があります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_sigv-create-signed-request.html)  開発プラットフォームが提供する標準の UriEncode 関数は、実装の違いや基礎となる RFC のあいまいさにより動作しない場合があります。エンコードが確実に機能するように、独自のカスタム UriEncode 関数を作成することをお勧めします。  Java での UriEncode 関数の例については、GitHub ウェブサイトで「[Java Utilities](https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66)」を参照してください。  | 

**注記**  
リクエストに署名するときは、AWS SigV4 または AWS SigV4a のいずれかを使用できます。これら 2 つの大きな違いを決定づけるのは、署名の計算方法です。SigV4a では、リージョンセットは署名する文字列に含まれますが、認証情報取得ステップの一部ではありません。

## 一時的なセキュリティ認証情報でリクエストに署名する
<a name="temporary-security-credentials"></a>

リクエストに署名するために長期的に認証情報を使用する代わりに、AWS Security Token Service (AWS STS) から提供された一時的なセキュリティ認証情報を使用できます。

一時的なセキュリティ認証情報を使用するときは、認可ヘッダーに `X-Amz-Security-Token` を追加するか、それをクエリ文字列に含めてセッショントークンを保持する必要があります。一部のサービスでは、正規リクエストに `X-Amz-Security-Token` を追加する必要があります。その他のサービスでは、署名の計算後に、`X-Amz-Security-Token` を末尾に追加するだけです。特定の要件については、AWS のサービスごとのドキュメントを確認してください。

## 署名手順の概要
<a name="create-signed-request-steps"></a>

**正規リクエストを作成する**  
リクエストのコンテンツ (ホスト、アクション、ヘッダーなど) を標準的な正規形式に変換します。正規リクエストは、署名文字列を作成するために使用される入力の 1 つです。正規リクエストの作成の詳細については、「[AWS API リクエスト署名の要素](reference_sigv-signing-elements.md)」を参照してください。

**正規リクエストのハッシュを作成する**  
ペイロードのハッシュを作成する際に使用したのと同じアルゴリズムを使用して、正規リクエストをハッシュ化します。正規リクエストのハッシュは、小文字の 16 進数文字の文字列として表す必要があります。

**署名文字列を作成する**  
正規リクエストに加えてアルゴリズム、リクエスト日、認証情報スコープ、正規リクエストのハッシュなどの追加情報を使用して、署名文字列を作成します。

**署名キーを取得する**  
シークレットアクセスキーを使用して、リクエストの署名に使用されるキーを取得します。

**署名を計算する**  
取得した署名キーをハッシュキーとして使用して、署名文字列に対してキー付きハッシュ操作を実行します。

**リクエストヘッダーに署名を追加する**  
算出した署名をリクエストの HTTP ヘッダーまたはクエリ文字列に追加します。

## 正規リクエストを作成する
<a name="create-canonical-request"></a>

正規リクエストを作成するには、次の文字列を改行文字で区切って連結します。これにより、自分で計算する署名と AWS が計算する署名とが必ず一致するようになります。

```
<HTTPMethod>\n
<CanonicalURI>\n
<CanonicalQueryString>\n
<CanonicalHeaders>\n
<SignedHeaders>\n
<HashedPayload>
```
+ *HTTPMethod* – `GET`、`PUT`、`HEAD`、`DELETE` などの HTTP メソッド。
+ *CanonicalUri* – 絶対パスコンポーネント URI の URI エンコード版 (ドメイン名の後の `/` から始まり、文字列の末尾まで、またはクエリ文字列パラメータがある場合は疑問符文字 (`?`) まで)。絶対パスが空値の場合は、フォワードスラッシュ文字 (`/`) を使用します。以下の例の URI (`/amzn-s3-demo-bucket/myphoto.jpg`) は絶対パスであるため、絶対パス内の `/` をエンコードしないでください。

  ```
  http://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.jpg
  ```
+ *CanonicalQueryString* – URI エンコードされたクエリ文字列パラメータ。それぞれの名前と値を個別に URI エンコードします。また、正規クエリ文字列内のパラメータをキー名のアルファベット順にソートする必要があります。ソートはエンコード後に行われます。次のサンプル URI のクエリ文字列は次のとおりです。

  ```
  http://s3.amazonaws.com/amzn-s3-demo-bucket?prefix=somePrefix&marker=someMarker&max-keys=2
  ```

  正規クエリ文字列は次のとおりです (この例では、読みやすいように改行が追加されています)。

  ```
  UriEncode("marker")+"="+UriEncode("someMarker")+"&"+
  UriEncode("max-keys")+"="+UriEncode("20") + "&" +
  UriEncode("prefix")+"="+UriEncode("somePrefix")
  ```

  リクエストがサブリソースをターゲットにしている場合、対応するクエリパラメータ値は空の文字列 (`""`) になります。例えば、次の URI は `amzn-s3-demo-bucket` バケット上の `ACL` サブリソースを特定してします。

   

  ```
  http://s3.amazonaws.com/amzn-s3-demo-bucket?acl
  ```

  この場合、CanonicalQueryString は以下のようになります。

   

  ```
  UriEncode("acl") + "=" + ""
  ```

  URI に `?` が含まれていない場合は、リクエストにクエリ文字列が存在しないため、正規クエリ文字列を空の文字列 (`""`) に設定します。この場合も、改行文字 (`"\n"`) を含める必要があります。
+ *CanonicalHeaders* – リクエストヘッダーとその値のリスト。個々のヘッダー名と値のペアは改行文字 (`"\n"`) で区切られます。以下は正規ヘッダーの例です。

  ```
  Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n"
  Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n"
  ...
  Lowercase(<HeaderNameN>)+":"+Trim(<value>)+"\n"
  ```

  CanonicalHeaders リストには以下が含まれている必要があります。
  + HTTP `host` ヘッダー。
  + `Content-Type` ヘッダーがリクエスト内に存在する場合は、それを *CanonicalHeaders* リストに追加する必要があります。
  + リクエストに含める予定の `x-amz-*` ヘッダーも追加する必要があります。例えば、一時的なセキュリティ認証情報を使用している場合は、リクエストに `x-amz-security-token` を含める必要があります。このヘッダーを *CanonicalHeaders* リストに追加する必要があります。
  + SigV4a の場合、リクエストが有効なリージョンセットを指定するリージョンセットヘッダーを含める必要があります。ヘッダー `X-Amz-Region-Set` はカンマ区切り値のリストとして指定されます。次の例は、us-east-1 リージョンと us-west-1 リージョンの両方でリクエストを行うことを許可するリージョンヘッダーを示しています。

    `X-Amz-Region-Set=us-east-1,us-west-1 `

    リージョンでワイルドカード (\$1) を使用して、複数のリージョンを指定できます。次の例では、ヘッダーを使用して、us-west-1 と us-west-2 の両方でリクエストを行うことができます。

    `X-Amz-Region-Set=us-west-*`
**注記**  
`x-amz-content-sha256` ヘッダーは Amazon S3 AWS リクエストに必要です。これにより、リクエストペイロードのハッシュが指定されます。ペイロードがない場合は、空の文字列のハッシュを指定する必要があります。

  各ヘッダー名は次の条件を満たす必要があります。
  + 小文字が使用されていること。
  + アルファベット順に表示されていること。
  + 後にコロン (`:`) が指定されていること。

  値については、次の操作を行う必要があります。
  + 先頭または末尾のスペースをすべて削除する。
  + 連続するスペースを 1 つのスペースに変換する。
  + 複数値ヘッダーの値をカンマで区切る。
  + host ヘッダー (HTTP/1.1) または :authority  ヘッダー (HTTP/2)、および任意の `x-amz-*` ヘッダーを署名に含める必要があります。署名には、content-type のような他の標準ヘッダーを指定することもできます。

  この例で使用されている関数 `Lowercase()` と `Trim()` は、前のセクションで説明されています。

  以下は `CanonicalHeaders` 文字列の例です。ヘッダー名は小文字で、ソートされています。

   

  ```
  host:s3.amazonaws.com
  x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  x-amz-date:20130708T220855Z
  ```

   
**注記**  
認可署名を計算する目的では、ホストと `x-amz-*` ヘッダーだけが必要です。ただし、データの改ざんを防ぐために、追加のヘッダーを署名計算に含めることを検討する必要があります。  
複雑なシステム間の転送中に頻繁に変更される hop-by-hop ヘッダーを含めないでください。これには `connection`、`x-amzn-trace-id`、`user-agent`、`keep-alive`、`transfer-encoding`、`TE`、`trailer`、`upgrade`、`proxy-authorization`、`proxy-authenticate` など、プロキシ、ロードバランサー、分散システムのノードによって変更されるすべての揮発性トランスポートヘッダーが含まれます。
+ *SignedHeaders* – アルファベット順にソートされ、セミコロンで区切られた小文字のリクエストヘッダー名のリスト。リスト内のリクエストヘッダーは、`CanonicalHeaders` 文字列に含めたヘッダーと同じです。前の例の場合、*SignedHeaders* の値は次のようになります。

  ```
  host;x-amz-content-sha256;x-amz-date
  ```
+ *HashedPayload* — HTTP リクエスト本文のペイロードをハッシュ関数への入力として使用して作成された文字列。この文字列には小文字の 16 進数文字を使用します。

  ```
  Hex(SHA256Hash(<payload>>))
  ```

  リクエストにペイロードがない場合は、空の文字列のハッシュを計算します。例えば、`GET` リクエストを使用してオブジェクトを取得する場合、ペイロードには何もありません。

  ```
  Hex(SHA256Hash(""))
  ```
**注記**  
Amazon S3 の場合、正規リクエストを作成するときにはリテラル文字列 `UNSIGNED-PAYLOAD` を含め、リクエストを送信するときには `x-amz-content-sha256` ヘッダー値と同じ値を設定します。  
`Hex(SHA256Hash("UNSIGNED-PAYLOAD"))`

## 正規リクエストのハッシュを作成する
<a name="create-canonical-request-hash"></a>

ペイロードのハッシュを作成する際に使用したのと同じアルゴリズムを使用して、正規リクエストのハッシュ (ダイジェスト) を作成します。正規リクエストのハッシュは、小文字の 16 進数文字の文字列として表す必要があります。

## 署名文字列を作成する
<a name="create-string-to-sign"></a>

署名文字列を作成するには、以下の文字列を改行文字で区切って連結します。この文字列は改行文字で終わらせないようにしてください。

```
Algorithm \n
RequestDateTime \n
CredentialScope  \n
HashedCanonicalRequest
```
+ *Algorithm* — 正規リクエストのハッシュを作成するために使用されるアルゴリズム。
  + SigV4a – `HMAC-SHA256` ハッシュアルゴリズムを指定するために `AWS4-HMAC-SHA256` を使用します 
  + SigV4a – `ECDSA-P256-SHA-256` ハッシュアルゴリズムを指定するために `AWS4-ECDSA-P256-SHA256` を使用します 
+ *RequestDateTime* — 認証情報のスコープで使用される日付と時刻。この値は、ISO 8601 形式の現在の UTC 時刻です (例: `20130524T000000Z`)。
+ *CredentialScope* - 認証情報スコープ。これにより、結果として生成した署名が、指定されたリージョンとサービスに制限されます。
  + SigV4 – 認証情報スコープには、アクセスキー ID、`YYYYMMDD` 形式の日付、リージョンコード、サービスコード、およびスラッシュ (/) で区切った `aws4_request` 終了文字列が含まれます。リージョンコード、サービスコード、および終了文字列には、小文字を使用する必要があります。この文字列は `YYYYMMDD/region/service/aws4_request` の形式になります。
  + SigV4a – 認証情報には、認証情報には、`YYYYMMDD` 形式の日付、サービス名、スラッシュ (/) で区切られた `aws4_request` 終了文字列が含まれます。このリージョンは別のヘッダー `X-Amz-Region-Set` でカバーされているため、認証情報スコープにはこのリージョンが含まれないことに注意してください。この文字列は `YYYYMMDD/service/aws4_request` の形式になります。
+ *HashedCanonicalRequest* - 前のステップで計算した正規リクエストのハッシュ。

以下は署名する文字列の例です。

```
"<Algorithm>" + "\n" +
timeStampISO8601Format + "\n" +
<Scope> + "\n" +
Hex(<Algorithm>(<CanonicalRequest>))
```

## 署名キーを取得する
<a name="derive-signing-key"></a>

署名キーを取得するには、次のいずれかのプロセスを選択して、SigV4 または SigV4a の署名キーを計算します。

### SigV4 の署名キーの取得
<a name="derive-signing-key-sigv4"></a>

SigV4 の署名キーを取得するには、最初のハッシュ操作のキーとして AWS のシークレットアクセスキーを使用して、リクエスト日、リージョン、およびサービスに対する一連のキー付きハッシュ操作 (HMAC) を実行します。

各ステップで、必要なキーとデータを使用してハッシュ関数を呼び出します。ハッシュ関数を呼び出すたびに、その結果はハッシュ関数への次の呼び出しの入力になります。

以下の例は、この手順の次のセクションで使用する `SigningKey` を取得する方法を示しています。入力内容は、この順序で連結されてハッシュ化されます。`HMAC-SHA256` は、以下に示すようにデータをハッシュ化する場合に使用されるハッシュ関数です。

```
DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>")
DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>")
DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>")
SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")
```

**入力必須**
+ `Key` – シークレットアクセスキーが含まれている文字列。
+ `Date` – 認証情報スコープで使用される日付が含まれている *YYYYMMDD* 形式の文字列。
+ `Region` – リージョンコードが含まれている文字列 (例: `us-east-1`)。

  リージョン文字列のリストについては、「AWS 全般のリファレンス」の「[リージョンとエンドポイント](https://docs.aws.amazon.com//general/latest/gr/rande.html#regional-endpoints)」を参照してください。
+ `Service` – サービスコードが含まれている文字列 (例: `ec2`)。
+ 上記の手順で作成したトピックを選択します。

**SigV4a の署名キーを取得するには**

1. `"AWS4"` とシークレットアクセスキーを連結します。データとしてのキーおよび日付文字列として、連結した文字列を備えたハッシュ関数を呼び出します。

   ```
   DateKey = hash("AWS4" + Key, Date)
   ```

1. データとしてのキーおよびリージョン文字列として、前回の結果を備えたハッシュ関数を呼び出します。

   ```
   DateRegionKey = hash(kDate, Region)
   ```

1. データとしてのキーおよびサービス文字列として、前回の結果を備えたハッシュ関数を呼び出します。

   サービスコードは、サービスによって定義されます。AWS Pricing CLI で [get-products](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/pricing/get-products.html) を使用して、サービスのサービスコードを返すことができます。

   ```
   DateRegionServiceKey = hash(kRegion, Service)
   ```

1. データとしてのキーおよび「aws4\$1request」として、前回の結果を備えたハッシュ関数を呼び出します

   ```
   SigningKey = hash(kService, "aws4_request")
   ```

### SigV4a の署名キーの取得
<a name="derive-signing-key-sigv4a"></a>

SigV4a の署名キーを作成するには、次のプロセスを使用してシークレットアクセスキーからキーペアを取得します。この取得の実装例については、「[C99 library implementation of AWS client-side authentication](https://github.com/awslabs/aws-c-auth/blob/e8360a65e0f3337d4ac827945e00c3b55a641a5f/source/key_derivation.c#L291.)」を参照してください。

```
n = [NIST P-256 elliptic curve group order]
G = [NIST P-256 elliptic curve base point]
label = "AWS4-ECDSA-P256-SHA256"

akid = [AWS access key ID as a UTF8 string]
sk = [AWS secret access Key as a UTF8 Base64 string]

input_key = "AWS4A" || sk
count = 1
while (counter != 255) {
  context = akid || counter // note: counter is one byte
  key = KDF(input_key, label, context, 256)
  c = Oct2Int(key)
  if (c > n - 2) {
    counter++
  } else {
    k = c + 1   // private key
    Q = k * G   // public key
  }
}

if (c < 255) {
  return [k, Q]
} else {
  return FAILURE
}
```

## 署名を計算する
<a name="calculate-signature"></a>

署名キーを取得したら、リクエストに追加する署名を計算します。この手順は、使用する署名のバージョンによって異なります。

**SigV4 の署名を計算するには**

1. 前回の呼び出しの結果をキー、**[署名する文字列]** をデータとしてハッシュ関数を呼び出します。取得した署名キーを、この操作のハッシュキーとして使用します。その結果、署名はバイナリ値になります。

   ```
   signature = hash(SigningKey, string-to-sign)
   ```

1. 署名を 2 進数から 16 進数表現に、小文字に変換します。

**SigV4a の署名を計算するには**

1. デジタル署名アルゴリズム (ECDSA P-256) を使用して、前のステップで作成した **[署名する文字列]** に署名します。この署名に使用されるキーは、上記のシークレットアクセスキーから派生したプライベート非対称キーです。

   ```
   signature = base16(ECDSA-Sign(k, string-to-sign))
   ```

1. 署名を 2 進数から 16 進数表現に、小文字に変換します。

## リクエストヘッダーに署名を追加する
<a name="add-signature-to-request"></a>

算出した署名をリクエストに追加します。

**Example 例: 認可ヘッダー**  
**SigV4**  
以下の例は、AWS SigV4 を使用する `DescribeInstances` アクションに対する `Authorization` ヘッダーを示しています。読みやすいように、この例では改行でフォーマットされています。コードでは、これは連続した文字列である必要があります。アルゴリズムと `Credential` の間にカンマはありません。ただし、他の要素はカンマで区切られている必要があります。

```
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=calculated-signature
```

**SigV4a**  
以下の例は、AWS SigV4a を使用する `CreateBucket` アクションに対する Authorization ヘッダーを示しています。読みやすいように、この例では改行でフォーマットされています。コードでは、これは連続した文字列である必要があります。アルゴリズムと認証情報の間にカンマはありません。ただし、他の要素はカンマで区切られている必要があります。

```
Authorization: AWS4-ECDSA-P256-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request,
SignedHeaders=host;x-amz-date;x-amz-region-set,
Signature=calculated-signature
```

**Example 例: クエリ文字列に認証パラメータを含むリクエスト**  
**SigV4**  
次の例は、認証情報を含む AWS SigV4 を使用する `DescribeInstances` アクションのクエリを示しています。読みやすいように、この例は改行でフォーマットされており、URL はエンコードされていません。コードでは、クエリ文字列は URL エンコードされた連続した文字列である必要があります。

```
https://ec2.amazonaws.com/?
Action=DescribeInstances&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date&
X-Amz-Signature=calculated-signature
```

**SigV4a**  
次の例は、認証情報を含む AWS SigV4a を使用する `CreateBucket` アクションのクエリを示しています。読みやすいように、この例は改行でフォーマットされており、URL はエンコードされていません。コードでは、クエリ文字列は URL エンコードされた連続した文字列である必要があります。

```
https://ec2.amazonaws.com/?
Action=CreateBucket&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request&
X-Amz-Region-Set=us-west-1&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date;x-amz-region-set&
X-Amz-Signature=calculated-signature
```

# リクエスト署名の例
<a name="reference_sigv-examples"></a>

以下の AWS 署名リクエストの例は、AWS SDK または AWS コマンドラインツールを使わずに送信されたリクエストに対して SigV4 を使用して署名する方法を示しています。

## HTTP POST を使用したブラウザベースの Amazon S3 アップロード
<a name="signature-v4-examples-s3-browser"></a>

 「[リクエストの認証: ブラウザベースのアップロード](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html)」では、Amazon S3 がリクエストを受け取るときに署名を計算するために使用する署名と関連情報について説明します。

「[例: HTTP POST を使用したブラウザベースのアップロード (AWS Signature Version 4 を使用)](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html)」では、サンプルの POST ポリシーおよびファイルのアップロードに使用できるフォームを含む詳細情報が提供されています。ポリシーと架空の認証情報の例は、ワークフローおよびその結果として生成される署名とポリシーハッシュを示しています。

## VPC Lattice で認証されたリクエスト
<a name="signature-v4-examples-lattice"></a>

 「[Signature Version 4 (SigV4) で認証されたリクエストの例](https://docs.aws.amazon.com/vpc-lattice/latest/ug/sigv4-authenticated-requests.html)」では、Python と Java の例が紹介されており、カスタムインターセプターを使用する場合と使用しない場合の両方でリクエスト署名を実行する方法が示されています。

## Amazon Translate での署名バージョン 4 の使用
<a name="signature-v4-examples-translate"></a>

 「[Live Translations in the Metaverse](https://aws.amazon.com/blogs/spatial/live-translations-in-the-metaverse/)」では、ほぼリアルタイムの翻訳ソリューションを生成するアプリケーションの構築方法を示しています。この音声翻訳ソリューションでは、イベントストリームエンコードで AWS SigV4 を使用して、リアルタイムに文字起こしを生成します。

## Neptune での Signature Version 4 の使用
<a name="signature-v4-examples-neptune"></a>

「[例: Signature Version 4 署名付き Python を使用して Neptune に接続する](https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth-connecting-python.html)」では、Python を使用して Neptune に署名付きリクエストを行う方法を示しています。この例には、アクセスキーや一時的な認証情報を使用するためのバリエーションが含まれています。

## Amazon Glacier への HTTP リクエストへの署名
<a name="signature-v4-examples-streaming-glacier"></a>

[ストリーミング API の署名計算例](https://docs.aws.amazon.com/amazonglacier/latest/dev/amazon-glacier-signing-requests.html)では、Amazon Glacier の 2 つのストリーミング API の 1 つであるアップロードアーカイブ (POST アーカイブ) の署名を作成する方法について詳しく説明します。

## Amazon SWF に対する HTTP リクエストの実行
<a name="signature-v4-examples-swf"></a>

[Amazon SWF への HTTP リクエストの作成](https://docs.aws.amazon.com/amazonswf/latest/developerguide/UsingJSON-swf.html#HTTPHeader) では、Amazon SWF への JSON リクエストのヘッダーの内容を示します。

## Amazon OpenSearch Service におけるストリーミング API のシグネチャ計算
<a name="signature-v4-examples-open-search"></a>

「[AWS SDK または PHP バージョン 3 で Amazon OpenSearch Service に署名する](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/service_es-data-plane.html)」では、署名された HTTP リクエストを Amazon OpenSearch サービスに送信する方法の例を示します。

## AWS サンプルリポジトリ内のプロジェクト例
<a name="signature-v4-examples-sdk"></a>

次のプロジェクト例では、Python、Node.js、Java、C\$1、Go、Rust などの一般的な言語を使用してリクエストに署名し、AWS サービスに Rest API リクエストを作成する方法を示します。

### 署名バージョン 4a のプロジェクト
<a name="signature-v4-examples-sigv4a"></a>

[sigv4-signing-examples](https://github.com/aws-samples/sigv4-signing-examples) プロジェクトでは、Python、Node.js、Java、C\$1、Go、Rust などの一般的な言語を使用して、SigV4 でリクエストに署名して AWS のサービス への Rest API リクエストを作成する方法の例を示します。

[sigv4a-signing-examples](https://github.com/aws-samples/sigv4a-signing-examples) プロジェクトでは、マルチリージョン API リクエストに署名するための例を提供しています。例えば、[Amazon S3 でのマルチリージョンアクセスポイント](https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiRegionAccessPoints.html)などです。

### Publish to AWS IoT Core
<a name="signature-v4-examples-iot-python"></a>

「[Python code to publish to AWS IoT Core using HTTPs protocol](https://github.com/aws-samples/aws-iot-core-python-node-sigv4-https)」では、HTTPS プロトコルと AWS SigV4 認証を使用してメッセージを AWS IoT Core にパブリッシュする方法を説明しています。これには 2 つのリファレンス実装があります。1 つは Python で、もう 1 つは NodeJS です。

「[.Net Framework application to publish to AWS IoT Core using HTTPs protocol](https://github.com/aws-samples/aws-iot-core-http-sigv4-dotnet-app)」では、HTTPS プロトコルと AWS SigV4 認証を使用してメッセージを AWS IoT Core にパブリッシュする方法を説明しています。このプロジェクトには、.NET Core と同等の実装も含まれています。

# AWS API リクエストの Signature Version 4 署名をトラブルシューティングする
<a name="reference_sigv-troubleshooting"></a>

**重要**  
AWS SDK または CLI を使用していない限り、リクエストの認証情報を提供する署名を計算するコードを記述する必要があります。SigV4 での署名計算は複雑な作業になる場合があるため、可能な限り AWS SDK または CLI を使用することをお勧めします。

署名リクエストを作成するコードを開発する際に、AWS のサービス が HTTP 403 `SignatureDoesNotMatch` エラーを表示する場合があります。これらのエラーは、AWS に対する HTTP リクエストの署名値が、AWS のサービス が計算した署名と一致しなかったことを意味します。HTTP 401 `Unauthorized` エラーは、アクセス許可によって呼び出し元がリクエストを行うことを許可されていない場合に返されます。

API リクエストは次の場合にエラーを返す可能性があります。
+ API リクエストは署名されておらず、API リクエストは IAM 認証を使用している場合。
+ リクエストの署名に使用された IAM 認証情報が正しくないか、API を呼び出す権限がない場合。
+ 署名された API リクエストの署名が、AWS サービスが計算した署名と一致していない場合。
+ API リクエストヘッダーが正しくない場合。

**注記**  
他のエラー解決策を検討する前に、AWS Signature Version 2 (SigV2) から AWS Signature Version 4 (SigV4) に更新してください。サービス (Amazon S3 など) とリージョンは SigV2 署名をサポートしなくなりました。

**Topics**
+ [認証情報エラー](#signature-v4-troubleshooting-credential)
+ [正規リクエストと署名文字列エラー](#signature-v4-troubleshooting-canonical-errors)
+ [認証情報範囲エラー](#signature-v4-troubleshooting-credential-scope)
+ [キー署名エラー](#signature-v4-troubleshooting-key-signing)

## 認証情報エラー
<a name="signature-v4-troubleshooting-credential"></a>

API リクエストが SigV4 で署名されていることを確認します。API リクエストが署名されていない場合、`Missing Authentication Token` のエラーが表示されることがあります。[足りない署名を追加して](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html#add-signature-to-request)、リクエストを再送信してください。

アクセスキーとシークレットキーの認証情報が正しいかどうか確認してください。アクセスキーが正しくない場合、`Unauthorized` のエラーが表示されることがあります。リクエストに署名したエンティティがリクエストを行う権限を持っていることを確認してください。詳細については、「[アクセス拒否エラーメッセージをトラブルシューティングする](troubleshoot_access-denied.md)」を参照してください。

## 正規リクエストと署名文字列エラー
<a name="signature-v4-troubleshooting-canonical-errors"></a>

[正規リクエストのハッシュを作成する](reference_sigv-create-signed-request.md#create-canonical-request-hash) または [署名文字列を作成する](reference_sigv-create-signed-request.md#create-string-to-sign) での正規化リクエストまたは署名する文字列を誤って計算した場合、サービスによって実行される署名の検証手順が失敗し、エラーメッセージが表示されます。

```
The request signature we calculated does not match the signature you provided
```

AWS サービスは署名されたリクエストを受け取ると、署名を再計算します。値に差があると、署名の一致に失敗します。正規リクエストと文字列を、署名付きリクエストとエラーメッセージの値と比較します。相違点がある場合は、署名プロセスを変更してください。

**注記**  
また、ヘッダーやリクエストを変更するプロキシ経由でリクエストを送信していないことを確認することもできます。

**Example 正規リクエストの例**  

```
GET                                                      -------- HTTP method
/                                                        -------- Path. For API stage endpoint, it should be /{stage-name}/{resource-path}
                                                         -------- Query string key-value pair. Leave it blank if the request doesn't have a query string.
content-type:application/json                            -------- Header key-value pair. One header per line.
host:0123456789.execute-api.us-east-1.amazonaws.com      -------- Host and x-amz-date are required headers for all signed requests.                       
x-amz-date:20220806T024003Z                              

content-type;host;x-amz-date                             -------- A list of signed headers
d167e99c53f15b0c105101d468ae35a3dc9187839ca081095e340f3649a04501        -------- Hash of the payload
```

シークレットキーがアクセス キー ID と一致することを確認するには、既知の動作する実装でテストします。例えば、AWS SDK または AWS CLI を使用して AWS へのリクエストを行います。

### API リクエストヘッダー
<a name="signature-v4-troubleshooting-credential-header"></a>

認可ヘッダーが空の場合、認証情報キーまたは署名が欠落しているか正しくない場合、ヘッダーがアルゴリズム名で始まらない場合、またはキーと値のペアに等号が含まれていない場合、次のいずれかのエラーが表示されます。
+ 認可ヘッダーを空にすることはできません。
+ 認可ヘッダーには「Credential」パラメータが必要です。
+ 認可ヘッダーには「Signature」パラメータが必要です。
+ 署名には、認可ヘッダーに無効な key=value ペア (等号の欠落) が含まれています。

[署名を計算する](reference_sigv-create-signed-request.md#calculate-signature) に追加された SigV4 認可ヘッダーに適切な資格情報キーが含まれていること、また、HTTP Date または `x-amz-date` ヘッダーを使用してリクエスト日が含まれていることを確認してください。

IncompleteSignatureException エラーが表示され、署名の構成が正しい場合は、クライアント側のリクエストで認可ヘッダーの SHA-256 ハッシュと B64 エンコードを計算することで、認可ヘッダーが AWS のサービス への転送中に変更されていないことを確認できます。

1. リクエストで送信した[認可ヘッダー](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html)を取得します。認可ヘッダーは次の例のようになります。

   ```
   Authorization: AWS4-HMAC-SHA256 
   Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request, 
   SignedHeaders=host;range;x-amz-date,
   Signature=example-generated-signature
   ```

1. 認可ヘッダーの SHA-256 ハッシュを計算します。

   ```
   hashSHA256(rawAuthorizationHeader) = hashedAuthorizationHeader
   ```

1. ハッシュ化された認可ヘッダーを Base64 形式にエンコードします。

   ```
   base64(hashedAuthorizationHeader) = encodedHashedAuthorizationHeader
   ```

1. 先ほど計算したハッシュ化およびエンコードされた文字列と、エラーメッセージで受け取った文字列を比較します。次の例に示すメッセージの例に似たメッセージが表示されます。

   ```
   com.amazon.coral.service#IncompleteSignatureException: 
   The signature contains an in-valid key=value pair (missing equal-sign) 
   in Authorization header (hashed with SHA-256 and encoded with Base64): 
   '9c574f83b4b950926da4a99c2b43418b3db8d97d571b5e18dd0e4f3c3ed1ed2c'.
   ```
+ 2 つのハッシュが異なる場合、認可ヘッダーの一部が転送中に変更されます。この変更は、ネットワークまたはクライアントハンドラーが署名付きヘッダーをアタッチしたり、何らかの方法で認可ヘッダーを変更したりすることが原因である可能性があります。
+ 2 つのハッシュが一致した場合、リクエストで送信した認可ヘッダーは、AWS が受信したものと一致します。受信したエラーメッセージを確認して、問題が誤った認証情報または署名の結果であるかどうかを確認します。これらのエラーについては、このページの他のセクションで説明します。

## 認証情報範囲エラー
<a name="signature-v4-troubleshooting-credential-scope"></a>

[署名文字列を作成する](reference_sigv-create-signed-request.md#create-string-to-sign) で作成された認証情報の範囲により、署名は特定の日付、リージョン、およびサービスに制限されます。この文字列は以下の形式になります。

```
YYYYMMDD/region/service/aws4_request
```

**注記**  
SigV4a を使用している場合、リージョンは認証情報のスコープに含まれません。

**日付**  
認証情報の範囲で x-amz-date ヘッダーと同じ日付が指定されていない場合、署名の検証手順が失敗し、次のエラーメッセージが表示されます。

```
Date in Credential scope does not match YYYYMMDD from ISO-8601 version of date from HTTP
```

リクエストで将来の時刻が指定されている場合、署名の検証ステップは次のエラーメッセージで失敗します。

```
Signature not yet current: date is still later than date
```

リクエストの有効期限が切れた場合、署名検証ステップは次のエラーメッセージで失敗します。

```
Signature expired: date is now earlier than date
```

**リージョン**  
認証情報の範囲でリクエストと同じリージョンが指定されていない場合、署名の検証ステップは次のエラーメッセージで失敗します。

```
Credential should be scoped to a valid Region, not region-code
```

**サービス**  
認証情報の範囲で host ヘッダーと同じサービスが指定されていない場合、署名の検証ステップは次のエラーメッセージで失敗します。

```
Credential should be scoped to correct service: 'service'
```

**終了文字列**  
認証情報の範囲が aws4\$1request で終わっていない場合、署名の検証ステップは次のエラーメッセージで失敗します。

```
Credential should be scoped with a valid terminator: 'aws4_request'
```

## キー署名エラー
<a name="signature-v4-troubleshooting-key-signing"></a>

署名キーの不正な取得や暗号の不適切な使用に起因するエラーは、トラブルシューティングがさらに困難です。正規文字列と署名文字列が正しいことが検証されたら、次の問題のいずれかを確認することもできます。
+ シークレットアクセスキーが、 指定したアクセスキー ID と一致しない。
+ キー取得コードに問題がある。

シークレットキーがアクセス キー ID と一致することを確認するには、既知の動作する実装でテストします。例えば、AWS SDK または AWS CLI を使用して AWS へのリクエストを行います。例については、「[リクエスト署名の例](reference_sigv-examples.md)」を参照してください。