リクエスト認証

本サービスへのアクセスはRESTベースのリクエストとして行なわれ、HTTPリクエストヘッダーに記述した認証ヘッダーにより正当性の検査が行なわれます。

リクエストボディ(ペイロード)の署名

署名バージョン4ではリクエストボディ(ペイロード)のハッシュ値の一部を署名計算に含めセキュリティを強化することができます。ペイロードのハッシュ値を署名に含めず計算、認証することも可能です。

ペイロードのハッシュ値を署名に含める場合

通常の送信方法(ペイロードの分割をしない)

ペイロードのハッシュ値全体を計算し、署名計算に含めることができます。これによりセキュリティが強化されますが、ペイロードを2回読み取るか、メモリにバッファーする必要があります。ペイロードが小さい場合は、この方法が適している場合があります。ただし、大きなファイルの場合、ファイルを2回読み取ると効率が悪くなる可能性があるため、データをチャンク単位でアップロードすることをお勧めします。詳細はこちらを参照ください。CanonicalRequestの作成時にペイロードのハッシュ値を含めます。x-iijgio-content-sha256ヘッダー値と同じ値を指定します。

ペイロードをチャンクに分割する場合

ペイロードの署名を計算の方法として、前述のようにペイロード全体を一度にハッシュ計算するのではなく、ペイロードを小さなチャンクに分割し、チャンク毎に署名を計算し認証する方式を提供しています。これによりペイロード全体を読み取って署名を計算する必要がなくなり、クライアント側での署名計算を効率的に行うことができます。最初のチャンクでは、リクエストヘッダーのみを使用するシードシグネチャを計算します。2番目のチャンクには、最初のチャンクの署名が含まれ、後続の各チャンクには、その前のチャンクの署名が含まれます。アップロードの最後に、ペイロードの最後のチャンクの署名を含む0バイトのデータを含む最終チャンクを送信します。詳細はシグネチャの内容(複数チャンク)を参照ください。

ペイロードのハッシュ値を署名に含めない場合

ペイロードのハッシュ値を署名の一部に利用しない場合は、CanonicalRequestの作成時にハッシュ値ではなくUNSIGNED-PAYLOADという文字列を含めてください。x-iijgio-content-sha256ヘッダーには同じ値をセットします。

Authorization: IIJGIO4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20130524/ap1/dag/iijgio4_request,
SignedHeaders=host;range;x-iijgio-date,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
要素
説明
IIJGIO4-HMAC-SHA256
署名の計算に使用されたアルゴリズム。認証にIIJGIO署名バージョン4を使用する場合は、この値を指定する必要があります。
文字列は、IIJGIO署名バージョン4(IIJGIO4)と署名アルゴリズム(HMAC-SHA256)を指定します。
Credential
アクセスキーIDと、署名の計算に使用された日付、リージョン、サービスを含むスコープ情報。
<your-access-key-id>/<date>/<iijgio-region>/<iijgio-service>/iijgio4_request
<date>値はYYYYMMDD フォーマットを使用して指定されます。
<iijgio-service> 値はdag、IIJGIO dagにリクエストを送信するときです。
SignedHeaders
署名の計算に使用したリクエストヘッダーのセミコロン区切りリスト。リストにはヘッダー名のみが含まれ、ヘッダー名は小文字にする必要があります。
host;range;x-iijgio-date
Signature
64ビットの小文字の16進文字として表される256ビットの署名。
fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
署名の計算は、ペイロードを転送するために選択したオプションによって異なることに注意してください。

シグネチャの内容

シグネチャ(Signature)の内容を以下に示します。以下署名計算は単一チャンクでの方法です。複数チャンクはシグネチャの内容(複数チャンク)をご参照ください。

signature = HexEncode(HMAC(<kSigningKey>, <StringToSign>))
kDate = HMAC("IIJGIO4" + <YourSecretAccessKey>, <YYYYMMDD>)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigningKey = HMAC(kService, "iijgio4_request")

StringToSign = <ALGORITHM> + "\n" +
<RequestDateTime> + "\n" +
<CredentialScope> + "\n" +
<HashedCanonicalRequest>

HashedCanonicalRequest = HexEncode(SHA256Hash(<CanonicalRequest>))

CanonicalRequest = <HTTPRequestMethod> + "\n" +
<CanonicalURI> + "\n" +
<CanonicalQueryString> + "\n" +
<CanonicalHeaders> + "\n" +
<SignedHeaders> + "\n" +
<HashedPayload>

CanonicalRequestの生成

<CanonicalURI>要素

URI の絶対パス要素の URI エンコードバージョンで、HTTP ホストヘッダーからクエリ文字列パラメータ (存在する場合) を開始する疑問符 (”?”) までのすべてを含みます。IIJGIO dagへのリクエストのURIパスを正規化しません。たとえば、「my-object//example//photo.user」という名前のオブジェクトを持つバケットがあるとします。パスを正規化すると、リクエスト内のオブジェクト名が「my-object/example/photo.user」に変更されます。これは、そのオブジェクトの誤ったパスです。

例)
http://storage-dag.iijgio.com/examplebucket/myphoto.jpg
CanonicalURI = /examplebucket/myphoto.jpg

<CanonicalQueryString>要素

URIエンコードされたクエリ文字列パラメーターを指定します。名前と値を個別にURIエンコードします。また、CanonicalQueryString のパラメータをキー名のアルファベット順に並べ替える必要があります。ソートはURIエンコード後に行われます。名前が重複しているパラメータは、値でさらにソートする必要があります。

擬似コード
UriEncode("marker")+"="+UriEncode("someMarker")+"&"+
UriEncode("max-keys")+"="+UriEncode("20") + "&" +
UriEncode("prefix")+"="+UriEncode("somePrefix")

※読みやすくするために、この例には改行が追加されています※UriEncode()はUriEncode()に詳細記載

例)
http://storage-dag.iijgio.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20
CanonicalQueryString = prefix=somePrefix&marker=someMarker&max-keys=20

リクエストがサブリソースを対象とする場合、対応するクエリパラメータ値は空の文字列(”“)になります。

例)
http://storage-dag.iijgio.com/examplebucket?acl
CanonicalQueryString = UriEncode("acl") + "=" + ""

URIに「?」が含まれていない場合、リクエストにはクエリ文字列がなく、CanonicalQueryString を空の文字列(”“)に設定します。「\n」を含める必要があります。

UriEncode()

すべてのバイトをURIエンコードします。

  • 予約されていない文字を除くすべてのバイトをURIエンコードします:「A」-「Z」、「a」-「z」、「0」-「9」、「-」、「。」、「_」、および「~」。
  • スペース文字は予約文字であり、「%20」(「+」ではなく)としてエンコードする必要があります。
  • 各URIエンコードバイトは、「%」とバイトの2桁の16進値で形成されます。
  • 16進値の文字は大文字にする必要があります(例: “%1A”)。
  • オブジェクトのキー名を除くすべての場所にスラッシュ文字「/」をエンコードします。

以下は、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();
    }

<CanonicalHeaders>要素

署名付きリクエストに含めるすべての HTTP ヘッダーのリストで構成されます。リストを作成するには、すべてのヘッダー名を小文字に変換し、先頭および末尾のスペースを削除します。ヘッダー値にある連続スペースを単一のスペースに変換します。リストには以下を含める必要があります。

  • HTTPホストヘッダー。
  • Content-Typeヘッダーがリクエストに存在する場合は、リストに追加する必要があります。
  • リクエストに含める予定のx-iijgio-*ヘッダーも追加する必要があります。たとえば、一時的なセキュリティ認証情報を使用している場合は、リクエストにx-iijgio-security-tokenを含める必要があり、リストにもこのヘッダーを追加する必要があります。
擬似コード
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN
CanonicalHeadersEntry = Lowercase(HeaderName) + ":" + Trimall(HeaderValue) + "\n"

※ Lowercase() : 全ての文字列を小文字に変換する関数※ Trimall() : 値の前後のスペースを削除し、連続するスペースを単一のスペースに変換する関数

リストを構築するには、(小文字の) ヘッダーを文字コードでソートし、ヘッダー名を繰り返し処理します。次のルールに従って各ヘッダーを作成します。

  • 小文字のヘッダー名とそれに続くコロンを追加します。
  • このヘッダーの値のカンマ区切りリストを追加します。複数の値を持つヘッダーの値はソートしません。
  • 改行 (\n) を追加します。

<SignedHeaders>要素

この値は、<CanonicalHeaders>要素に含めたヘッダーのリストです。

SignedHeaders = Lowercase(HeaderName0) + ";" + Lowercase(HeaderName1) + ";" + ... + Lowercase(HeaderNameN)

※ Lowercase() : 全ての文字列を小文字に変換する関数* すべてのヘッダー名を小文字に変換してソートし、セミコロンで連結します。

<HashedPayload>要素

ペイロードのSHA256ハッシュの16進値です。

ペイロードの構造

HexEncode(SHA256Hash(<payload>)
// リクエストにペイロードがない場合
HexEncode(SHA256Hash(""))

CanonicalRequestのハッシュを生成

HashedCanonicalRequest = HexEncode(SHA256Hash(<CanonicalRequest>))  //前手順で求めたCanonicalRequest
  • ペイロードのハッシュ計算と同じアルゴリズムで作成します。

StringToSignを生成

StringToSign = <ALGORITHM> + "\n" +
<RequestDateTime> + "\n" +
<CredentialScope> + "\n" +
<HashedCanonicalRequest>    //前手順で求めたCanonicalRequestのハッシュ値

ALGORITHM定数

IIJGIO署名のバージョンと、署名の計算に使用したアルゴリズムを識別します。IIJGIO署名バージョン4の場合、このパラメーター値を「IIJGIO4-HMAC-SHA256」に設定します。 この文字列は、IIJGIO署名バージョン4(IIJGIO4)とHMAC-SHA256アルゴリズム(HMAC-SHA256)を識別します。

<RequestDateTime>要素

リクエスト日付。日付は、ISO8601 基本形式を使用し、x-iijgio-date ヘッダーで YYYYMMDD’T’HHMMSS’Z’ 形式で指定します。この値は、前のステップで使用した値と一致する必要があります。

<CredentialScope>要素

<requestDate>/<regionName>/<serviceName>/iijgio4_request

次の順序の文字列をスラッシュで区切ったものです。

1.リクエストの年(YYYY)、月(MM)、日(DD)を表す 8 桁の文字列としての日付情報(例: 20150830)。

2.小文字の英数字の文字列としてのリージョン情報。サービスのエンドポイントの一部であるリージョン名を使用します。

3.小文字の英数字の文字列としてのサービス名情報(例: dag)。

4.特殊な終了文字列: 「iijgio4_request」

signatureを計算

signature = HexEncode(HMAC(<kSigningKey>,     //下記参照
<StringToSign>))        //前手順で求めたStringToSign
kDate = HMAC("IIJGIO4" + <YourSecretAccessKey>, <YYYYMMDD>)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigningKey = HMAC(kService, "iijgio4_request")

最終的なAuthorizationヘッダー

Authorization: <ALGORITHM> Credential=<YourSecretAccessKey>/<CredentialScope>, SignedHeaders=<SignedHeaders>, Signature=<signature>
  • <ALGORITHM> と Credential の間にカンマはありません。ただし、SignedHeaders と Signature は、前の値とカンマで区切られています。

シグネチャの内容(複数チャンク)

  1. ペイロードのチャンクサイズを決定します。チャンクサイズは少なくとも8 KBである必要があります。パフォーマンスを向上させるには、64 KB以上のチャンクサイズをお勧めします。このチャンクサイズは、最後のチャンクを除くすべてのチャンクに適用されます。送信する最後のチャンクは、8 KB未満にすることができます。ペイロードが小さく、1つのチャンクに収まる場合は、8 KB未満にすることができます。
  2. 最初のチャンクに含めるためのシード署名を作成します。
  3. 最初のチャンクを作成してストリーミングします。
  4. 後続の各チャンクについて、署名する文字列に前の署名を含むチャンク署名を計算し、チャンクを作成して送信します。
  5. 他のチャンクと同じ最終的な追加チャンクを送信しますが、データバイトはゼロです。

シード署名の計算

signature = HexEncode(HMAC(<kSigningKey>, <StringToSign>))
kDate = HMAC("IIJGIO4" + <YourSecretAccessKey>, <YYYYMMDD>)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigningKey = HMAC(kService, "iijgio4_request")

StringToSign = <ALGORITHM> + "\n" +
<RequestDateTime> + "\n" +
<CredentialScope> + "\n" +
<HashedCanonicalRequest>

HashedCanonicalRequest = HexEncode(SHA256Hash(<CanonicalRequest>))

CanonicalRequest = <HTTPRequestMethod> + "\n" +
<CanonicalURI> + "\n" +
<CanonicalQueryString> + "\n" +
<CanonicalHeaders> + "\n" +
<SignedHeaders> + "\n" +
"STREAMING-IIJGIO4-HMAC-SHA256-PAYLOAD"

チャンク署名の計算

signature = HexEncode(HMAC(<kSigningKey>, <StringToSign>))

kDate = HMAC("IIJGIO4" + <YourSecretAccessKey>, <YYYYMMDD>)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigningKey = HMAC(kService, "iijgio4_request")

StringToSign = "IIJGIO4-HMAC-SHA256-PAYLOAD" + "\n" +
<RequestDateTime> + "\n" +
<CredentialScope> + "\n" +
<lastChunkSignature> + "\n" +
HexEncode(SHA256Hash("")) + "\n" +
HexEncode(SHA256Hash(currentChunkData)

次のように異なることを除いて、単一チャンクとプロセスは同じです。追加する予定のリクエストヘッダーに加えて、次のヘッダーを含める必要があります。

ヘッダー名
説明
x-iijgio-content-sha256
このヘッダーは、すべての署名バージョン4リクエストに必要です。値をSTREAMING-IIJGIO4-HMAC-SHA256-PAYLOADに設定して、署名がヘッダーのみをカバーし、ペイロードがないこと を示します。
Content-Encoding
値をiijgio-chunkedに設定します。
本サービスは複数のコンテンツエンコーディングをサポートしています。
例)Content-Encoding : iijgio-chunked,gzip
つまり、Signature Version 4ストリーミングAPIを使用するときに、カスタムコンテンツエンコーディングを指定できます。
注意)本サービスは、iijgio-chunkedエンコーディングなしで結果のオブジェクトを保存します。
したがって、オブジェクトを取得するとき、それはiijgio-chunkedエンコードされません。
x-iijgio-decoded-content-length
メタデータをカウントせずに、チャンク化するデータの長さ(バイト単位)を設定します。たとえば、4 GBのファイルをアップロードする場合は、値を4294967296に設定します。これは、アップロードするオブジェクト(本サービスに保存するデータ)のrawサイズです。
Content-Length
送信されたHTTP本文の実際のサイズに設定します。これには、データの長さ(x-iijgio-decoded-content-lengthに設定された値)とチャンクメタデータが含まれます。各チャンクには、前のチャンクの署名などのメタデータがあります。

チャンクボディ

string(IntHexBase(chunk-size)) + ";chunk-signature=" + signature + \r\n + chunk-data + \r\n
  • IntHexBase()整数 : チャンクサイズを16進数に変換するために記述する関数
  • chunk-size : メタデータなしのチャンクデータのサイズ(バイト単位)です。たとえば、65 KBのオブジェクトをアップロードし、64 KBのチャンクサイズを使用する場合、3つのチャンクでデータをアップロードします。最初のチャンクは64 KB、2番目は1 KB、最後のチャンクは0バイトです。
  • signature : 各チャンクについて、前述の「チャンク署名の計算」で署名を計算します。最初のチャンクでは、前の署名としてシード署名を使用します。

クエリ文字列認証

認証情報を HTTP リクエストヘッダーに追加する代わりに、クエリ文字列に認証情報を含めることができます。クエリパラメータを使用してリクエストを認証すると、リクエストを完全にURLで表現したい場合に役立ちます。

署名済みURLのユースケースシナリオは、IIJGIO dagリソースへの一時的なアクセスを許可できることです。たとえば、署名済みURLをWebサイトに埋め込んだり、コマンドラインクライアント(Curlなど)で使用してオブジェクトをダウンロードしたりできます。

署名の作成方法

https://storage-dag.iijgio.com/examplebucket/test.txt
?X-Iijgio-Algorithm=IIJGIO4-HMAC-SHA256
&X-Iijgio-Credential=<your-access-key-id>/20130721/ap1/dag/iijgio4_request
&X-Iijgio-Date=20130721T201207Z
&X-Iijgio-Expires=86400
&X-Iijgio-SignedHeaders=host
&X-Iijgio-Signature=<signature-value>

URLのX-Iijgio-Credential値は、読みやすくするために「/」文字を示しています。実際には、%2Fとしてエンコードする必要があります。

&X-Iijgio-Credential=<your-access-key-id>%2F20130721%2Fap1%2Fdag%2Fiijgio4_request

X-Iijgio-Algorithm

ALGORITHM定数を参照

X-Iijgio-Credential

<CredentialScope>要素を参照

X-Iijgio-Date

日付と時刻の形式はISO 8601標準に準拠している必要があり、「yyyyMMddTHHmmssZ」形式でフォーマットする必要があります。たとえば、日付と時刻が「2016/08/01 15:32:41.982-700」の場合、まずUTC(協定世界時)に変換してから、「20160801T083241Z」として送信する必要があります。

X-Iijgio-Expires

生成された署名済みURLが有効な期間を秒単位で提供します。 たとえば、86400(24時間)です。 この値は整数です。 設定できる最小値は1で、最大値は604800(7日)です。署名済みURLは、署名の計算に使用する署名鍵が最大7日間有効であるため、最大7日間有効です。

X-Iijgio-SignedHeaders

<SignedHeaders>要素を参照

X-Iijgio-Signature

signatureを計算参照

署名付きURLでのCanonicalRequestの作成が次のように異なることを除いて、プロセスは通常同じです。

  • 署名付きURLを作成するとき、URLが任意のペイロードのアップロードに使用されるため、ペイロードのコンテンツがわからないため、Canonicalリクエストにペイロードハッシュを含めません。代わりに、定数文字列UNSIGNED-PAYLOADを使用します。
  • CanonicalRequest には、X-Iijgio-Signatureを除く、前の表のすべてのクエリパラメーターを含める必要があります。
  • CanonicalHeaders には、HTTPホストヘッダーを含める必要があります。 x-iijgio-* ヘッダーのいずれかを含める予定の場合は、これらのヘッダーも署名の計算に追加する必要があります。オプションで、リクエストに含める予定のその他すべてのヘッダーを追加できます。セキュリティを強化するには、できるだけ多くのヘッダーに署名する必要があります。

ページ先頭へ