Authorization ヘッダーの署名計算: 単一チャンクでのペイロードの転送 (AWS 署名バージョン 4)
Authorization ヘッダーを使用してリクエストを認証する場合、ヘッダー値には特に署名が含まれます。署名の計算は、ペイロードの転送 (概要) の選択によって異なります。このセクションでは、ペイロードを単一のチャンクで転送することを選択した場合の署名計算について説明します。サンプルセクション (例: 署名計算 を参照) には、コードを検証するためのテストスイートとして使用できる署名計算と結果として生成される Authorization ヘッダーが表示されます。
重要
ペイロードを単一のチャンクで転送する場合、署名計算にペイロードハッシュを含めることをオプションで選択できます。これを含める場合、署名付きペイロードと呼ばれます (含めない場合、ペイロードは署名なしと見なされます)。次のセクションで説明する署名手順は両方に適用されますが、次の違いに注意してください。
-
署名付きペイロードオプション – 正規リクエストを作成するときにペイロードハッシュを含めます (署名計算セクションで説明されているように、これは StringToSign の一部になります)。また、リクエストを S3 に送信するときに、
x-amz-content-sha256ヘッダー値と同じ値を指定します。 -
署名なしペイロード – 正規リクエストを作成するときにはリテラル文字列
UNSIGNED-PAYLOADを含め、Amazon S3 にリクエストを送信するときにも、その文字列と同じ値をx-amz-content-sha256ヘッダー値として設定します。
Amazon S3 にリクエストを送信すると、x-amz-content-sha256 ヘッダー値はペイロードが署名されているかどうかを Amazon S3 に通知します。その後、Amazon S3 は検証のためにそれに応じて署名を作成できます。
どちらの場合も、x-amz-content-sha256 ヘッダーの値は既に HashedPayload の一部であるため、x-amz-content-sha256 ヘッダーを正規ヘッダーとして含める必要はありません。
署名の計算
署名を計算するには、まず署名する文字列が必要です。次に、署名キーを使用して署名する文字列の HMAC-SHA256 ハッシュを計算します。次の図は、署名用に作成する文字列のさまざまなコンポーネントを含むプロセスを示しています
Amazon S3 は、認証されたリクエストを受信すると、署名を計算し、その署名をリクエスト内で提供された署名と比較します。そのため、署名は Amazon S3 で使用されているものと同じ方法で計算する必要があります。署名のために、リクエストを承認済み形式にするプロセスは正規化と呼ばれます。
次の表では、図に示されている関数について説明します。これらの関数のコードを実装する必要があります。
| 関数 | 説明 |
|---|---|
Lowercase() |
文字列を小文字に変換します。 |
Hex() |
16 進数の小文字エンコード。 |
SHA256Hash() |
セキュアハッシュアルゴリズム (SHA) 暗号化ハッシュ関数。 |
HMAC-SHA256() |
指定した署名キーで SHA256 アルゴリズムを使用して HMAC を計算します。これが最後の署名です。 |
Trim() |
先頭または末尾の空白をすべて削除します。 |
UriEncode() |
すべてのバイトが URI でエンコードされます。UriEncode() は、以下のルールを適用する必要があります。
重要開発プラットフォームが提供する標準の UriEncode 関数は、実装の違いや基礎となる RFC のあいまいさにより動作しない場合があります。エンコードが確実に機能するように、独自のカスタム UriEncode 関数を作成することをお勧めします。 Java の UriEncode() 関数の例を次に示します。
|
タスク 1: 正規リクエストを作成する
このセクションでは、正規リクエストの作成の概要を説明します。
以下は、Amazon S3 が署名の計算に使用する正規リクエスト形式です。署名を一致させるには、次の形式で正規リクエストを作成する必要があります。
<HTTPMethod>\n<CanonicalURI>\n<CanonicalQueryString>\n<CanonicalHeaders>\n<SignedHeaders>\n<HashedPayload>
説明は以下のとおりです。
-
HTTPMethodは、GET、PUT、HEAD、DELETE などの HTTP メソッドの 1 つです。 -
CanonicalURIとは、URI の絶対パスコンポーネントの URI エンコード版です。ドメイン名の後の「/」から始まり、文字列の末尾まで、またはクエリ文字列パラメータがある場合は疑問符文字 (「?」) までの部分を指します。次の例の URI、/examplebucket/myphoto.jpgは絶対パスであるため、ユーザーは絶対パス内の「/」をエンコードしないでください。http://s3.amazonaws.com/examplebucket/myphoto.jpg注記
Amazon S3 へのリクエストにおいて、URI パスを正規化することはありません。例えば、「my-object//example//photo.user」という名前のオブジェクトを持つバケットがあるとします。パスを正規化すると、リクエストのオブジェクト名が「my-object/example/photo.user」に変更されます。これは、そのオブジェクトの正しくないパスです。
-
CanonicalQueryStringは、URI エンコードされたクエリ文字列パラメータを指定します。名前と値を個別に URI エンコードします。また、正規クエリ文字列内のパラメータをキー名のアルファベット順にソートする必要があります。ソートはエンコード後に行われます。次のサンプル URI のクエリ文字列は次のとおりです。prefix=somePrefix&marker=someMarker&max-keys=20http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20正規クエリ文字列は次のとおりです (この例では、読みやすいように改行が追加されています)。
UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix")リクエストがサブリソースをターゲットにしている場合、対応するクエリパラメータ値は空の文字列 ("") になります。例えば、次の URI は
examplebucketバケット上のACLサブリソースを特定してします。http://s3.amazonaws.com/examplebucket?aclこの場合の CanonicalQueryString は次のとおりです。
UriEncode("acl") + "=" + ""URI に「?」が含まれていない場合は、リクエストにクエリ文字列が存在しないため、正規クエリ文字列を空の文字列 ("") に設定します。「\n」は引き続き含める必要があります。
-
CanonicalHeadersは、リクエストヘッダーとその値のリストです。個々のヘッダー名と値のペアは改行文字 (「\n」) で区切られます。ヘッダー名は小文字である必要があります。次の例に示すように、文字列を作成するには、ヘッダー名をアルファベット順にソートする必要があります。Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n" Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n" ... Lowercase(<HeaderNameN>)+":"+Trim(<value>)+"\n"この例で使用されている関数
Lowercase()とTrim()は、前のセクションで説明されています。CanonicalHeadersリストには以下が含まれている必要があります。-
HTTP
hostヘッダー。 -
Content-MD5ヘッダーがリクエスト内に存在する場合は、それをCanonicalHeadersリストに追加する必要があります。 -
リクエストに含める予定の
x-amz-*ヘッダーも追加する必要があります。例えば、一時的なセキュリティ認証情報を使用している場合は、リクエストにx-amz-security-tokenを含める必要があります。このヘッダーをCanonicalHeadersリストに追加する必要があります。
注記
x-amz-content-sha256ヘッダーは、すべての AWS 署名バージョン 4 リクエストに必要です。これにより、リクエストペイロードのハッシュが指定されます。ただし、S3 はリクエストで送信されるペイロードのハッシュを計算するときに自動的にその値を使用するため、x-amz-content-sha256を正規ヘッダーとして含める必要はありません。ペイロードがない場合は、空の文字列のハッシュを指定する必要があります。
S3 でリクエストのハッシュと照合しない場合は、代わりにリテラル文字列
"UNSIGNED-PAYLOAD"を使用できます。
以下は
CanonicalHeaders文字列の例です。ヘッダー名は小文字で、ソートされています。例例 1
host:s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130708T220855Z例例 2
host:s3.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD x-amz-date:20130708T220855Z例例 3
host:s3.amazonaws.com x-amz-date:20130708T220855Z注記
認可署名を計算するには、ホストヘッダーと
x-amz-content-sha256を除くすべてのx-amz-*ヘッダーが必要です。ただし、データの改ざんを防ぐために、署名計算にすべてのヘッダーを含めることを検討する必要があります。S3 は受信したリクエストペイロードハッシュを計算するときにその値を使用するため、
x-amz-content-sha256ヘッダーへの署名はオプションです。 -
-
SignedHeadersは、アルファベット順にソートされ、セミコロンで区切られた小文字のリクエストヘッダー名のリストです。リスト内のリクエストヘッダーは、CanonicalHeaders文字列に含めたヘッダーと同じです。前の例の場合、SignedHeadersの値は次のようになります。例例 1 と 2
host;x-amz-content-sha256;x-amz-date例例 3
host;x-amz-date -
HashedPayloadは、リクエストペイロードの SHA256 ハッシュの 16 進値です。Hex(SHA256Hash(<payload>)リクエストにペイロードがない場合は、空の文字列のハッシュを次のように計算します。
Hex(SHA256Hash(""))ハッシュは次の値を返します。
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855例えば、PUT リクエストを使用してオブジェクトをアップロードする場合、本文にオブジェクトデータを指定します。GET リクエストを使用してオブジェクトを取得する場合、空の文字列ハッシュを計算します。
タスク 2: 署名文字列を作成する
このセクションでは、署名する文字列の作成の概要を説明します。ステップバイステップの手順については、「AWS 全般のリファレンス」の「タスク 2: 署名する文字列を作成する」を参照してください。
署名する文字列は、次の文字列を連結したものです。
"AWS4-HMAC-SHA256" + "\n" + timeStampISO8601Format + "\n" +<Scope>+ "\n" + Hex(SHA256Hash(<CanonicalRequest>))
定数文字列 AWS4-HMAC-SHA256 は、使用しているハッシュアルゴリズム HMAC-SHA256 を指定します。timeStamp は、ISO 8601 形式の現在の UTC 時刻です (例: 20130524T000000Z)。
Scope は、生成された署名を特定の日付、AWS リージョン、およびサービスにバインドします。したがって、生成された署名は、特定のリージョンおよび特定のサービスでのみ機能します。署名は、指定された日付から 7 日間有効です。
date.Format(<YYYYMMDD>) + "/" +<region>+ "/" +<service>+ "/aws4_request"
Amazon S3 の場合、サービス文字列は s3 です。region 文字列のリストについては、「AWS 全般のリファレンス」の「リージョンとエンドポイント」を参照してください。この表のリージョン列には、有効なリージョン文字列のリストが表示されます。
次のスコープは、生成される署名を us-east-1 リージョンと Amazon S3 に制限します。
20130606/us-east-1/s3/aws4_request
注記
Scope は、次のセクションで説明するように、署名キーの計算に使用するのと同じ日付を使用する必要があります。
タスク 3: 署名を計算する
AWS 署名バージョン 4 では、リクエストの署名に AWS アクセスキーを使用するのではなく、特定のリージョンおよびサービスにスコープされた署名キーを最初に作成します。 署名キーの詳細については、「リクエストへの署名の概要」を参照してください。
DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>") DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>") SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")
注記
一部のユースケースでは、署名キーを最大 7 日間処理できます。詳細については、「他ユーザーとのオブジェクトの共有」を参照してください。
リージョン文字列のリストについては、「AWS 全般のリファレンス」の「リージョンとエンドポイント」を参照してください。
署名キーを使用すると、AWS 認証情報を 1 つの安全な場所に保持できます。例えば、Amazon S3 と通信するサーバーが複数ある場合は、署名キーをそれらのサーバーと共有します。各サーバーにシークレットアクセスキーのコピーを保持する必要はありません。署名キーは最大 7 日間有効です。したがって、署名キーを計算するたびに、署名キーをサーバーと共有する必要があります。詳細については、「リクエストの認証 (AWS 署名バージョン 4)」を参照してください。
最後の署名は、署名キーをキーとして使用し、署名する文字列に対して HMAC-SHA256 を適用して得られるハッシュ値です。
HMAC-SHA256(SigningKey, StringToSign)
署名を作成するステップバイステップの手順については、「AWS 全般のリファレンス」の「タスク 3: 署名を作成する」を参照してください。
例: 署名計算
このセクションの例を参考にして、コード内の署名計算を確認できます。例に示す計算では、次のデータを使用します。
-
アクセスキーの例。
パラメータ 値 AWSAccessKeyIdAKIAIOSFODNN7EXAMPLEAWSSecretAccessKeywJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -
リクエストのタイムスタンプ 20130524T000000Z (
Fri, 24 May 2013 00:00:00 GMT)。 -
バケット名
examplebucket。 -
バケットは米国東部 (バージニア北部) リージョンにあると見なされます。認証情報
ScopeとSigning Key計算では、us-east-1をリージョン指定子として使用します。リージョンの詳細については、「AWS 全般のリファレンス」の「リージョンとエンドポイント」を参照してください。 -
パススタイルまたは仮想ホスト形式のリクエストのいずれかを使用できます。次の例は、仮想ホスト形式のリクエストに署名する方法を示しています。例えば、次のようになります。
https://examplebucket.s3.amazonaws.com/photos/photo1.jpg詳細については、「Amazon Simple Storage Service ユーザーガイド」の「バケットの仮想ホスティング」を参照してください。
例: GET Object
次の例では、examplebucket からオブジェクト (test.txt) の最初の 10 バイトを取得します。API アクションの詳細については、「GetObject」を参照してください。
GET /test.txt HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedRange: bytes=0-9 x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date: 20130524T000000Z
この GET リクエストは本文コンテンツを提供しないため、x-amz-content-sha256 の値は空のリクエスト本文のハッシュまたはリテラル文字列 "UNSIGNED-PAYLOAD" のいずれかになります。次の手順は、空の文字列のハッシュを使用して署名を計算し、Authorization ヘッダーを構成する方法を示しています。
-
StringToSign
-
CanonicalRequest
GET /test.txt host:examplebucket.s3.amazonaws.com range:bytes=0-9 x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;range;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855正規リクエスト文字列の最後の行は、空のリクエスト本文のハッシュです。リクエストにクエリパラメータが含まれていないため、3 行目は空です。
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41 -
Authorization ヘッダー
その結果得られる
Authorizationヘッダーは以下のようになります。AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
例: PUT Object
この PUT リクエストの例では、examplebucket にオブジェクト (test$file.text) を作成します。例では、次のように想定しています。
-
x-amz-storage-classリクエストヘッダーを追加して、ストレージクラスとしてREDUCED_REDUNDANCYをリクエストしています。ストレージクラスの詳細については、「Amazon Simple Storage Service ユーザーガイド」の「ストレージクラス」を参照してください。 -
アップロードされたファイルのコンテンツは、
"Welcome to Amazon S3."という文字列です。リクエストのx-amz-content-sha256の値はこの文字列に基づいています。
API アクションの詳細については、「PutObject」を参照してください。
PUT test$file.text HTTP/1.1 Host: examplebucket.s3.amazonaws.com Date: Fri, 24 May 2013 00:00:00 GMT Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY x-amz-content-sha256: 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072<Payload>
次の手順は、署名の計算を示しています。
-
StringToSign
-
CanonicalRequest
PUT /test%24file.text date:Fri, 24 May 2013 00:00:00 GMT host:examplebucket.s3.amazonaws.com x-amz-content-sha256:44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072 x-amz-date:20130524T000000Z x-amz-storage-class:REDUCED_REDUNDANCY date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072リクエストにクエリパラメータがないため、正規リクエストの 3 行目は空です。
x-amz-content-sha256正規ヘッダーは、ペイロードハッシュがリクエストの末尾に既に提供されているため、オプションで署名できます。最後の行は本文のハッシュで、HTTP リクエストで S3 に送信されるx-amz-content-sha256 header値と同じである必要があります。 -
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 9e0e90d9c76de8fa5b200d8c849cd5b8dc7a3be3951ddb7f6a76b4158342019d
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd -
Authorization ヘッダー
その結果得られる
Authorizationヘッダーは以下のようになります。AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd
例: GET Bucket Lifecycle
次の GET リクエストは、examplebucket のライフサイクル設定を取得します。API アクションの詳細については、「GetBucketLifecycleConfiguration」を参照してください。
GET ?lifecycle HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
リクエストは本文コンテンツを提供しないため、x-amz-content-sha256 ヘッダー値は空のリクエスト本文のハッシュです。次の手順は、署名の計算を示しています。
-
StringToSign
-
CanonicalRequest
GET / lifecycle= host:examplebucket.s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855正規リクエストの最後の行は、空のリクエスト本文のハッシュです。
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 9766c798316ff2757b517bc739a67f6213b4ab36dd5da2f94eaebf79c77395ca
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543 -
Authorization ヘッダー
その結果得られる
Authorizationヘッダーは以下のようになります。AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543
例: バケットの取得 (オブジェクトの一覧表示)
次の例では、examplebucket バケットからオブジェクトのリストを取得します。API アクションの詳細については、「ListObjects」を参照してください。
GET ?max-keys=2&prefix=J HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
リクエストは本文を提供しないため、x-amz-content-sha256 の値は空のリクエスト本文のハッシュです。次の手順は、署名の計算を示しています。
-
StringToSign
-
CanonicalRequest
GET / max-keys=2&prefix=J host:examplebucket.s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855正規文字列の最後の行は、空のリクエスト本文のハッシュです。
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request df57d21db20da04d7fa30298dd4488ba3a2b47ca3a489c74750e0f1e7df1b9b7
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7 -
Authorization ヘッダー
その結果得られる
Authorizationヘッダーは以下のようになります。AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7