View a markdown version of this page

Authorization ヘッダーの署名計算: 複数チャンクでのペイロードの転送 (チャンクアップロード) (AWS 署名バージョン 4) - Amazon Simple Storage Service

Authorization ヘッダーの署名計算: 複数チャンクでのペイロードの転送 (チャンクアップロード) (AWS 署名バージョン 4)

概要 で説明されているように、Authorization ヘッダーを使用してリクエストを認証する場合、ペイロードをチャンクでアップロードするオプションがあります。固定サイズまたは可変サイズのチャンクでデータを送信できます。このセクションでは、チャンクアップロードの署名計算プロセス、チャンクボディの作成方法、チャンクを最初にアップロードした後に後続のチャンクで署名を送信する遅延署名の仕組みについて説明します。サンプルセクション (例: PUT Object を参照) には、コードを検証するためのテストスイートとして使用できる署名計算と結果として生成される Authorization ヘッダーが表示されます。

注記

一連のチャンクとしてデータを転送する場合は、次のいずれかを実行する必要があります。

  • Content-Length HTTP ヘッダーを使用して、コンテンツの合計長 (オブジェクト長のバイト数と各チャンクのメタデータの合計) を明示的に指定します。これを行うには、リクエストを開始する前に、各チャンクで送信するメタデータを含むペイロードの合計長を事前に計算する必要があります。

  • Transfer-Encoding HTTP ヘッダーを指定します。Transfer-Encoding ヘッダーを含め、identity 以外の値を指定する場合は、Content-Length ヘッダーを省略する必要があります。

すべてのリクエストについて、オブジェクトのサイズをバイト単位で指定する x-amz-decoded-content-length ヘッダーを含める必要があります。

各チャンクの署名の計算には、前のチャンクの署名が含まれます。最初に、ヘッダーのみを使用してシード署名を作成します。シード署名は、最初のチャンクの署名計算に使用します。後続の各チャンクについて、前のチャンクの署名を含むチャンク署名を作成します。このように、チャンク署名は互いに連結されます。つまり、チャンク n の署名は F(チャンク n, 署名(チャンク n-1)) という関数になります。連鎖により、チャンクを正しい順序で送信できます。

チャンクアップロードを実行するには、以下を実行します。

  1. ペイロードのチャンクサイズを決定します。これは、コードを記述するときに必要になります。

    チャンクサイズは 8 KB 以上である必要があります。パフォーマンスを向上させるため、64 KB 以上のチャンクサイズをお勧めします。このチャンクサイズは、最後のチャンクを除くすべてのチャンクに適用されます。送信する最後のチャンクは 8 KB 未満でも構いません。ペイロードが小さく、1 つのチャンクに収まる場合、8 KB 未満にすることができます。

  2. 最初のチャンクに含めるシード署名を作成します。詳細については、「シード署名の計算」を参照してください。

  3. 最初のチャンクを作成してストリーミングします。詳細については、「チャンクボディの定義」を参照してください。

  4. 後続のチャンクごとに、署名対象文字列に前の署名を含むチャンク署名を計算し、チャンクを作成して送信します。詳細については、「チャンクボディの定義」を参照してください。

  5. 最後の追加チャンクを送信します。これは、構築内の他のチャンクと同じですが、データバイト数はゼロです。詳細については、「チャンクボディの定義」を参照してください。

シード署名の計算

次の図は、シード署名を計算するプロセスを示しています。

シード署名を計算するプロセス。

次の表では、図に示されている関数について説明します。これらの関数のコードを実装する必要があります。

関数 説明
Lowercase() 文字列を小文字に変換します。
Hex() 16 進数の小文字エンコード。
SHA256Hash() セキュアハッシュアルゴリズム (SHA) 暗号化ハッシュ関数。
HMAC-SHA256() 指定した署名キーで SHA256 アルゴリズムを使用して HMAC を計算します。これが最後の署名です。
Trim() 先頭または末尾の空白をすべて削除します。
UriEncode()

すべてのバイトが URI でエンコードされます。UriEncode() は、以下のルールを適用する必要があります。

  • 非予約文字 (「A」-「Z」、「a」-「z」、「0」-「9」、「-」、「.」、「_」および「~」) を除くすべてのバイトが URI でエンコードされます。

  • スペース文字は予約文字であるため、「+」ではなく「%20」としてエンコードする必要があります。

  • URI で エンコードされた各バイトは、「%」とそのバイトの 2 桁の 16 進値で構成されています。

  • 16 進値の文字は大文字である必要があります (例:「%1A」)。

  • オブジェクトキー名以外では、フォワードスラッシュ文字「/」がエンコードされます。例えば、オブジェクトキー名が photos/Jan/sample.jpg の場合、キー名のフォワードスラッシュはエンコードされません。

重要

開発プラットフォームが提供する標準の UriEncode 関数は、実装の違いや基礎となる RFC のあいまいさにより動作しない場合があります。エンコードが確実に機能するように、独自のカスタム UriEncode 関数を作成することをお勧めします。

Java の UriEncode() 関数の例を次に示します。

public static String UriEncode(CharSequence input, boolean encodeSlash) { StringBuilder result = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') { result.append(ch); } else if (ch == '/') { result.append(encodeSlash ? "%2F" : ch); } else { result.append(toHexUTF8(ch)); } } return result.toString(); }

署名プロセスについては、「Authorization ヘッダーの署名計算: 単一チャンクでのペイロードの転送 (AWS 署名バージョン 4)」を参照してください。プロセスは同じですが、CanonicalRequest の作成は次のように異なります。

  • 追加するリクエストヘッダーに加えて、次のヘッダーを含める必要があります。

    ヘッダー 説明
    x-amz-content-sha256

    このヘッダーは、すべての AWS 署名バージョン 4 リクエストに必要です。値を STREAMING-AWS4-HMAC-SHA256-PAYLOAD に設定して、署名がヘッダーのみを対象とし、ペイロードが含まれないことを示します。

    Content-Encoding

    値を aws-chunked に設定します。

    Amazon S3 は、複数のコンテンツエンコーディング値をサポートしています。署名バージョン 4 ストリーミング API を使用する場合は、カスタムのコンテンツエンコードを指定できます。

    例えば、次のようになります。

    Content-Encoding : aws-chunked,gzip

    Amazon S3 は、content-encoding ヘッダーに aws-chunked 値を含めずに、生成されたオブジェクトを保存します。content-encoding ヘッダーに渡す値が aws-chunked のみである場合、S3 は content-encoding ヘッダーを空と見なし、オブジェクトの取得時にこのヘッダーを返しません。

    x-amz-decoded-content-length メタデータをカウントせずに、チャンクするデータの長さをバイト単位で設定します。例えば、4 GB のファイルをアップロードする場合は、値を 4294967296 に設定します。これは、アップロードするオブジェクト (Amazon S3 に保存するデータ) の raw サイズです。
    Content-Length

    この値を、送信される HTTP 本文の実際のサイズに設定します。このサイズには、データ (x-amz-decoded-content-length に設定された値) に加えて、チャンクメタデータの長さも含まれます。各チャンクには、前のチャンクの署名などのメタデータがあります。チャンクの計算については、次のセクションで説明します。Transfer-Encoding ヘッダーを含め、identity 以外の値を指定する場合は、Content-Length ヘッダーを含めないでください。

シード署名と共に最初のチャンクを送信します。次のセクションで説明するように、チャンクを作成する必要があります。

チャンクボディの定義

すべてのチャンクにはメタデータが含まれています。各チャンクは、次の構造に従う必要があります。

string(IntHexBase(chunk-size)) + ";chunk-signature=" + signature + \r\n + chunk-data + \r\n

説明は以下のとおりです。

  • IntHexBase() は、整数のチャンクサイズを 16 進数に変換するために記述する関数です。例えば、チャンクサイズが 65536 の場合、16 進数の文字列は「 10000」となります。

  • chunk-size は、メタデータを含まないチャンクデータのサイズをバイト単位で表したものです。例えば、65 KB のオブジェクトを 64 KB のチャンクサイズでアップロードする場合、データは 3 つのチャンクに分けてアップロードされます。つまり 1 つ目は 64 KB、2 つ目は 1 KB、最後のチャンクは 0 バイトです。

  • signature チャンクごとに、次の署名する文字列を使用して署名を計算します。最初のチャンクでは、シード署名を前の署名として使用します。

    署名する文字列のさまざまなコンポーネントを示すシード署名を計算するプロセス。

送信する最後のチャンクデータのサイズは 0 ですが、チャンクボディには、前のチャンクの署名を含むメタデータが含まれます。

例: PUT Object

このセクションの例を参考にして、コード内の署名計算を確認できます。例を確認する前に、次の点に注意してください。

  • これらの例の署名計算では、次のサンプルのセキュリティ認証情報を使用します。

    パラメータ
    AWSAccessKeyId AKIAIOSFODNN7EXAMPLE
    AWSSecretAccessKey wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • すべての例では、リクエストのタイムスタンプとして 20130524T000000Z (Fri, 24 May 2013 00:00:00 GMT) を使用します。

  • すべての例では、バケット名として examplebucket を使用します。

  • バケットは米国東部 (バージニア北部) リージョンにあると見なされ、認証情報の ScopeSigning Key の計算ではリージョン指定子として us-east-1 が使用されます。詳細については、Amazon Web Services 全般のリファレンスリージョンとエンドポイントを参照してください。

  • パススタイルまたは仮想ホスト形式のリクエストのいずれかを使用できます。次の例では、仮想ホスト形式のリクエストを使用します。次に例を示します。

    https://examplebucket.s3.amazonaws.com/photos/photo1.jpg

    詳細については、「Amazon Simple Storage Service ユーザーガイド」の「バケットの仮想ホスティング」を参照してください。

次の例では、オブジェクトをアップロードする PUT リクエストを送信します。署名の計算では、次のことを前提としています。

  • 65 KB のテキストファイルをアップロードしようとしています。ファイルの内容は文字「a」で構成される 1 文字の文字列です。

  • チャンクサイズは 64 KB です。その結果、ペイロードは 3 つのチャンク (64 KB、1 KB、およびチャンクデータが 0 バイトの最後のチャンク) に分けてアップロードされます。

  • 生成されるオブジェクトのキー名は chunkObject.txt です。

  • x-amz-storage-class リクエストヘッダーを追加して、ストレージクラスとして REDUCED_REDUNDANCY をリクエストしています。

API アクションの詳細については、「PutObject」を参照してください。一般的なリクエストの構文は次のとおりです。

PUT /examplebucket/chunkObject.txt HTTP/1.1 Host: s3.amazonaws.com x-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY Authorization: SignatureToBeCalculated x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD Content-Encoding: aws-chunked x-amz-decoded-content-length: 66560 Content-Length: 66824 <Payload>

次の手順は、署名の計算を示しています。

  1. シード署名 – 署名する文字列を作成する
    1. CanonicalRequest

      PUT /examplebucket/chunkObject.txt content-encoding:aws-chunked content-length:66824 host:s3.amazonaws.com x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD x-amz-date:20130524T000000Z x-amz-decoded-content-length:66560 x-amz-storage-class:REDUCED_REDUNDANCY content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class STREAMING-AWS4-HMAC-SHA256-PAYLOAD

      リクエストにクエリパラメータがないため、正規リクエストの 3 行目は空です。最後の行は、ハッシュされたペイロードの値として提供される定数文字列で、x-amz-content-sha256 header の値と同じである必要があります。

    2. StringToSign

      AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455

      注記

      署名する文字列の各行については、シード署名の計算を説明する図を参照してください。

  2. SigningKey

    signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request")

  3. シード署名

    4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  4. Authorization ヘッダー

    その結果得られる Authorization ヘッダーは以下のようになります。

    AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9

  5. チャンク 1: (65536 バイト、文字「a」の値 97)
    1. 署名するチャンク文字列。

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a

      注記

      署名する文字列の各行の詳細については、署名する文字列のさまざまなコンポーネントを示す前述の図を参照してください (例えば、最後の 3 行は、previous-signaturehash("")、および hash(current-chunk-data) です)。

    2. チャンク署名。

      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
    3. 送信されたチャンクデータ。

      10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 <65536-bytes>
  6. チャンク 2: (1024 バイト、文字「a」の値 97)
    1. 署名するチャンク文字列。

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
    2. チャンク署名。

      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
    3. 送信されたチャンクデータ。

      400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 <1024 bytes>
  7. チャンク 3: (0 バイトのデータ)
    1. 署名するチャンク文字列。

      AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    2. チャンク署名。

      b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
    3. 送信されたチャンクデータ。

      0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9