シグネチャーバージョン 4 生成方法
シグネチャーバージョン4を使ってニフクラにリクエストを送信するサンプルを示しながら、シグネチャの作成方法を解説します。
シグネチャーを生成する手順と、実際にシグネチャーを使用してリクエストを送信する例を示します。
サンプルリクエスト・認証情報
サンプルリクエストは、ニフクラ RDBにファイアウォールグループを作成する以下を使用します。
GET
https://jp-east-1.rdb.api.nifcloud.com/?Action=CreateDBSecurityGroup&NiftyAvailabilityZone=east-11&DBSecurityGroupDescription=テストファイアウォール&DBSecurityGroupName=test-fire-wall HTTP/1.1
Host: jp-east-1.rdb.api.nifcloud.com
X-Nifty-Date: 20160427T025932Z
また、ニフクラAPIでは、ユーザー認証に下記のような認証情報を用います。
アクセスキー | 12345678901234567890 |
---|---|
シークレットアクセスキー | 1234567890abcdefghijklmnopqrstuvwxyzABCD |
これらの認証情報は、コントロールパネルのアカウントメニューから取得することができます。
シグネチャー生成手順
正規化リクエストの作成
シグネチャー生成のために、はじめにリクエストを正規化します。
ニフクラのAPIサーバーは、受け取ったリクエストにある情報からシグネチャーを作成し、リクエストのシグネチャーと比較します。
ニフクラのシグネチャー生成手順に従うことで、正しいシグネチャーを得ることができます。
正規化リクエストのテンプレートは、下記の通りです。
正規化リクエストのテンプレート
HTTPRequestMethod + '\n' +
CanonicalURI + '\n' +
CanonicalQueryString + '\n' +
CanonicalHeaders + '\n' +
SignedHeaders + '\n' +
HexEncode(Hash(RequestPayload))
テンプレートを追いながら、正規化の手順を説明します。
HTTPRequestMethod
1行目のHTTPRequestMethodには、リクエストの方法に合わせて「GET」あるいは「POST」を指定します。
サンプルリクエストのHTTPRequestMethod
GET
CanonicalURI
2行目のCanonicalURIには、絶対パスをURLエンコードしたものを指定します。(URLのドメイン部分から「?」マークまでの間の部分を指定します。)
上述の例では、「...nifcloud.com/?Action=...」と続いているため、絶対パスは存在しません。絶対パス部分がない場合は、/ を指定します。
サンプルリクエストのCanonicalURI
/
CanonicalQueryString
3行目のCanonicalQueryStringには、クエリストリングを正規化したものを指定します。
リクエストがクエリストリングを含まない場合は、empty string(長さ0の文字列)です。
正規化クエリストリングを構成するためには、以下の手順を実施します。
パラメーター名と値をURLエンコードします。
このルールに従って文字列をエンコードする関数やメソッドが、複数の言語で用意されています。
- RFC3986に定義されている非予約文字はエンコードしません。
(非予約文字とは「A-Z、a-z、0-9、ハイフン(-)、アンダースコア(_)、ピリオド(.)、チルダ(~)」を指します。) - ほかのすべての文字列について、%XY によるURLエンコードを行います。
(XとYは、16進コード文字列(0-9および大文字のA-F)です。例えば、半角スペースはパーセントエンコーディングで「%20」に符号化します。)
それぞれのパラメーター名とパラメーター値を'='で結合し、パラメーターを「&」で結合します。ただし最後のパラメーターには不要です。
以上の手順を実施した例が、下記となります。
サンプルリクエストのURLクエリパラメーター
Action=CreateDBSecurityGroup
NiftyAvailabilityZone=east-11
DBSecurityGroupDescription=テストファイアウォール
DBSecurityGroupName=test-fire-wall
上記のリクエストパラメーターは、サンプルリクエストのパラメーターを並べたものです。
これを上述の手順に従って処理すると、正規化クエリストリングは以下になります。
サンプルリクエストのCanonicalQueryString
Action=CreateDBSecurityGroup&DBSecurityGroupDescription=%E3%83%86%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB&DBSecurityGroupName=test-fire-wall&NiftyAvailabilityZone=east-11
CanonicalHeaders
4行目のCanonicalHeadersには、正規化したヘッダーパラメーターを指定します。
ヘッダーパラメーターには、hostやX-Nifty-Dateを含めます。
サンプルリクエストはGETメソッドなので、ヘッダパラメーターは下記の通りです。
サンプルリクエストのヘッダパラメーター
Host: jp-east-1.rdb.api.nifcloud.com
X-Nifty-Date: 20160427T025932Z
正規化ヘッダーの作成テンプレートは、下記の通りです。
CanonicalHeadersのテンプレート
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN
CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'
正規化の手順は、下記の通りです。
先ほどのサンプルヘッダーを上述のテンプレートに従って正規化すると以下になります。
サンプルリクエストのCanonicalHeaders
host:jp-east-1.rdb.api.nifcloud.com\n
x-nifty-date:20160427T025932Z\n
SignedHeaders
5行目のSignedHeadersには、ヘッダーパラメータのパラメータ名のリストを指定します。
ヘッダーパラメーター名は小文字変換する必要があります
先ほど正規化したサンプルヘッダーからパラメーター名のみを取り出して、「;」で結合しパラメーター名のリストを作成します。
サンプルリクエストのSignedHeaders
host;x-nifty-date
HashedPayload
6行目のHexEncode(Hash(RequestPayload))は、HTTPリクエストのボディ部の内容(ここではペイロードと呼びます)をハッシュ化し、16進数エンコードしたものを指定します。
多くの言語でハッシュ化および16進数エンコードの関数やメソッドが用意されています。
ニフクラのシグネチャバージョン 4では、「SHA-256」というアルゴリズムでハッシュ化を行います。
GETリクエストを利用するなど、ペイロードが空の場合には、empty string(長さ0の文字列)を使用します。
サンプルリクエストのペイロード
''(empty string)
上記のペイロードをハッシュ化した値は、下記の通りです。
サンプルリクエスト:ハッシュ化ペイロード
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
正規化リクエスト(CanonicalRequest)の作成
正規化リクエストに必要な項目が揃ったら、最初に示した以下のテンプレートに従って、それぞれ作成した文字列を結合します。
1. GET
2. /
3. Action=CreateDBSecurityGroup&DBSecurityGroupDescription=%E3%83%86%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB&DBSecurityGroupName=test-fire-wall&NiftyAvailabilityZone=east-11
4. host:jp-east-1.rdb.api.nifcloud.com
5. x-nifty-date:20160427T025932Z
6.
7. host;x-nifty-date
8. e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- ※説明のために行番号を追加してあります。
- ※6行目に改行が含まれているのは、CanonicalHeadersの最後に改行コードが含まれ、さらに改行コードが 追加されているためです。
署名文字列・署名キーの作成
署名文字列の作成
署名文字列もシグネチャーを生成するのに必要な文字列です。
リクエストおよび手順1で作成した正規化リクエストより生成します。
署名文字列は、アルゴリズム・日付・証明範囲・ハッシュ化された正規化リクエストを、以下のように改行で結合した文字列です。
署名文字列 =
Algorithm + '\n' +
RequestDate + '\n' +
CredentialScope + '\n' +
Hash(CanonicalRequest)
サンプルリクエストの署名文字列の各項目は、次のような手順で作成します。
Algorithm
手順1の6番目、ペイロードのハッシュ化の手順で利用したアルゴリズムを指定します。
下記の「NIFTY4-HMAC-SHA256」のほか、「AWS-HMAC-256」も指定できます。
サンプルリクエストのAlgorithm
NIFTY4-HMAC-SHA256
RequestDate
この項目は、X-Nifty-Dateを指定します。
サンプルリクエストのRequestDate
20160427T025932Z
CredentialScope
この項目は、下記の通りにデータを並べます。
日付(YYYYMMDD様式)/リージョン/サービス識別子/nifty4_request
サンプルリクエストでは、下記の値を使用し作成します。
日付 | 20160427 |
---|---|
リージョン | east-1 |
サービス識別子 | rdb |
上記の例のほかに、利用可能リージョンやバージョン 4を利用可能なサービスについては、下記ページにてご確認ください。
サンプルリクエストのCredentialScope
20160427/east-1/rdb/nifty4_request
Hash(CanonicalRequest)
この項目は、手順1の7番目で作成した正規化リクエストを、ペイロードをハッシュ化したのと同じ手法でハッシュ化したものです。
サンプルリクエストのHash(CanonicalRequest)
a306d8074f9a44d5bb7817ae52c5482744d7d8c84bd0a353a8d16a77e9fc4ffa
署名文字列を作る
必要な項目を最初に示したとおりに結合すると、下記のようになります。
この署名文字列を使って、次の手順でシグネチャーを生成します。
サンプルリクエストの署名文字列
NIFTY4-HMAC-SHA256\n
20160427T025932Z\n
20160427/east-1/rdb/nifty4_request\n
a306d8074f9a44d5bb7817ae52c5482744d7d8c84bd0a353a8d16a77e9fc4ffa
署名キーの作成
シグネチャー 4では、「シークレットアクセスキー」ではなく「シークレットアクセスキーから引き出したキー(署名キー)」を使って署名します。
シグネチャーを算出するために、まずはシークレットアクセスキーから署名キー(kSigning)を作成します。
- ※サンプルリクエストに使用するシークレットアクセスキーは、冒頭に記載したものを使用します。
署名キーの作成方法
kSecret = シークレットアクセスキー
kDate = HMAC("NIFTY4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "nifty4_request")
HMAC(key、data)は、HMAC-SHA256によるハッシュ化機能を示しています。
HMACでハッシュ化する関数やメソッドが、各種プログラミング言語で提供されています。
サンプルリクエストでは、下記の通りとなります。
kSecret = 1234567890abcdefghijklmnopqrstuvwxyzABCD
Date = 20160427
Region = east-1
Service = rdb
上記を使用し先述の方法に従って作成すると、下記のようになります。
サンプルリクエストの署名キー
fd9626ac4e58ab692ce8654bebb4a0628fa974d596e9e800cf6c016e80ed41d8
※ 署名キーを16進数として出力した結果です。
シグネチャーを生成
作成した署名キーを使ってシグネチャを生成します。 シグネチャーの生成方法は以下の通りです。
シグネチャーの生成方法
signature = HexEncode(HMAC(署名key, 署名文字列))
※ 署名キーは先述のサンプルに示した16進数として表示した値ではなく、kSigning の生の値を利用します。HMACでハッシュ化した値を16進数エンコードします。
サンプルリクエストに対してこの処理を実行すると下記の値となり、これを使用して認証を行うことができます。
サンプルリクエストのシグネチャー
75870a7e8db8687ad8d4a4eacf027854444ffa587dc9eb00c86a9594f5b11866
リクエスト送信例
生成したシグネチャーと、curlコマンドを使ってサンプルリクエストを送信してみます。
URLの形式は、下記の通りです。
<エンドポイント>/?<CanonicalQueryString>
そのため、サンプルリクエストのURLは、下記のようになります。
https://jp-east-1.rdb.api.nifcloud.com/?Action=CreateDBSecurityGroup&DBSecurityGroupDescription=%E3%83%86%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB&DBSecurityGroupName=test-fire-wall&NiftyAvailabilityZone=east-11
先ほど生成したシグネチャーはヘッダー情報に含めます。
ヘッダー情報に必須なパラメーターは、「X-Nifty-Date」と「Authorization」です。
Authorizationパラメーターは、以下のテンプレートに従いハッシュ化アルゴリズム・アクセスキー・シグネチャーを設定します。
Authorization:<ハッシュ化アルゴリズム>
Credential=<アクセスキー>/<CredentialScope>,
SignedHeaders=<SignedHeaders>, Signature=<シグネチャー>
このテンプレートに従うと、サンプルリクエストの「Authorization」は、下記の通りとなります。
Authorization:NIFTY4-HMAC-SHA256
Credential=12345678901234567890/20160427/east-1/rdb/nifty4_request,
SignedHeaders=host;x-nifty-date,
Signature=75870a7e8db8687ad8d4a4eacf027854444ffa587dc9eb00c86a9594f5b11866
以上の情報を組み合わせると、curlを使ってリクエストを送信する例は、下記のようになります。
curl
'https://jp-east-1.rdb.api.nifcloud.com/?Action=CreateDBSecurityGroup&DBSecurityGroupDescription=%E3%83%86%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB&DBSecurityGroupName=test-fire-wall&NiftyAvailabilityZone=east-11'
\
--get \
--header 'x-nifty-date:20160427T025932Z' \
--header 'Authorization:NIFTY4-HMAC-SHA256
Credential=12345678901234567890/20160427/east-1/rdb/nifty4_request,
SignedHeaders=host;x-nifty-date,
Signature=75870a7e8db8687ad8d4a4eacf027854444ffa587dc9eb00c86a9594f5b11866'