シグネチャーバージョン 4 生成方法
シグネチャーバージョン4の生成方法を解説しながら、ニフクラにリクエストを送信するサンプルを示します。
- サンプルとしてニフクラRDB APIのシグネチャーバージョン4認証を取り上げます。
- RDB APIでは、RDB:共通リクエスト・レスポンスに記載の通り、必須ヘッダーであるX-Amz-DateとAuthorizationを指定します。
- サービスによって必須ヘッダーは異なります。詳細は各サービスのAPIドキュメントを参照してください。
サンプルリクエスト・認証情報
ニフクラ RDBにファイアウォールグループを作成する、下記サンプルリクエストを使用します。
GET
https://jp-east-1.rdb.api.nifcloud.com/?Action=CreateDBSecurityGroup&DBSecurityGroupDescription=テストファイアウォール&DBSecurityGroupName=test-fire-wall&NiftyAvailabilityZone=east-11 HTTP/1.1
Host: jp-east-1.rdb.api.nifcloud.com
X-Amz-Date: 20221026T014354Z
ニフクラAPIの認証情報は下記とします。
アクセスキー | 12345678901234567890 |
シークレットアクセスキー | 1234567890abcdefghijklmnopqrstuvwxyzABCD |
これらの認証情報は、コントロールパネルのアカウントメニューから取得できます。
クラウド操作方法ガイド(アカウントメニュー:アクセスキー)
シグネチャー生成手順
1. 正規化リクエストの作成
シグネチャー生成のために、はじめにリクエストを正規化します。
ニフクラの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には、正規化したクエリストリングを指定します。クエリストリングを含まないリクエストは、長さ0の文字列であるempty stringを指定してください。
正規化クエリストリングを構成するには、下記の手順を実行します。
パラメーター名と値をURLエンコードします。
このルールに従って文字列をエンコードする関数やメソッドが、複数の言語で用意されています。- RFC3986に定義されている非予約文字はエンコードしません。
非予約文字とは「A-Z、a-z、0-9、-(ハイフン)、_(アンダースコア)、.(ピリオド)、~(チルダ)」を指します。 - 他のすべての文字列は、%XY によるURLエンコードを実行します。
XとYは、「0-9および大文字のA-F」からなる16進コード文字列です。例えば、半角スペースはパーセントエンコーディングで「%20」に符号化します。
- RFC3986に定義されている非予約文字はエンコードしません。
パラメーター名をASCIIコード順にソートします。
ソートリストの先頭のパラメーター名から順に、正規化クエリストリングに追加します。
各パラメーター名とパラメーター値を’=’で結合し、パラメーターを「&」で結合します。ただし、最後のパラメーターに「&」は不要です。
以上の手順を実行した例を、下記に示します。
サンプルリクエストのURLクエリパラメーター:
Action=CreateDBSecurityGroup
DBSecurityGroupDescription=テストファイアウォール
DBSecurityGroupName=test-fire-wall
NiftyAvailabilityZone=east-11
上記クエリパラメーターは、サンプルリクエストのパラメーターを並べています。
本パラメーターを上記の手順に従い処理すると、クエリストリングは下記のように正規化されます。
サンプルリクエストの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-Amz-Dateを含めます。
サンプルリクエストはGETメソッドなので、ヘッダーパラメーターは下記の通りです。
サンプルリクエストのヘッダーパラメーター:
Host: jp-east-1.rdb.api.nifcloud.com
X-Amz-Date: 20221026T014354Z
正規化ヘッダーの作成テンプレートは、下記の通りです。
CanonicalHeadersのテンプレート
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN
CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'
正規化の手順は、下記の通りです。
- ヘッダー名を小文字に変換し、余分なスペースを取り除きます。
- ヘッダー名とヘッダー値を「:」で結合します。このとき、引用符(“~”)の外側にあるスペースは取り除きます。
- ヘッダー値のリストは「,」でセパレートします。
- ヘッダーの重複がある場合も「,」でセパレートします。
- ヘッダーの中で、値のソートは実施しません。
- 改行のため「\n」を追加します。
先ほどのサンプルヘッダーを上記テンプレートに従って処理すると、下記のように正規化されます。
サンプルリクエストのCanonicalHeaders:
host:jp-east-1.rdb.api.nifcloud.com\n
x-amz-date:20221026T014354Z\n
SignedHeaders
5行目のSignedHeadersには、ヘッダーパラメーターのパラメーター名のリストを指定します。ヘッダーパラメーター名は小文字に変換します。
先ほど正規化したサンプルヘッダーからパラメーター名のみを取り出し、「;」で結合してパラメーター名のリストを作成します。
サンプルリクエストのSignedHeaders:
host;x-amz-date
HashedPayload
6行目のHexEncode(Hash(RequestPayload))は、HTTPリクエストのボディ部の内容(ここではペイロードと呼びます)をハッシュ化し、16進数エンコードした値を指定します。
多くの言語でハッシュ化および16進数エンコードの関数やメソッドが用意されています。ニフクラのシグネチャーバージョン 4では、「SHA-256」というアルゴリズムでハッシュ化します。
GETリクエストを利用するなど、ペイロードが空の際には、長さ0の文字列であるempty stringを使用します。
サンプルリクエストのペイロード:
''(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-amz-date:20221026T014354Z
6.
7. host;x-amz-date
8. e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
※行番号は説明のために付与しています。
※6行目に改行が含まれているのは、CanonicalHeadersの末尾に改行コードが含まれ、さらに改行コードが追加されているためです。
2. 署名文字列・署名キーの作成
署名文字列の作成
署名文字列もシグネチャーを生成するのに必要な文字列です。リクエストおよび手順1で作成した正規化リクエストから生成します。
署名文字列は、アルゴリズム、日付、証明範囲、ハッシュ化された正規化リクエストを、下記の形式で改行して結合した文字列です。
署名文字列 =
Algorithm + '\n' +
RequestDate + '\n' +
CredentialScope + '\n' +
Hash(CanonicalRequest)
サンプルリクエストの署名文字列の各項目は、下記の手順で作成します。
Algorithm
手順1の6番目「HashedPayload」ペイロードのハッシュ化の手順で利用したアルゴリズム「AWS4-HMAC-SHA256」を指定します。
サンプルリクエストのAlgorithm:
AWS4-HMAC-SHA256
RequestDate
X-Amz-Dateを指定します。
サンプルリクエストのRequestDate:
20221026T014354Z
CredentialScope
下記の形式でデータを並べます。
日付(YYYYMMDD様式)/リージョン/サービス識別子/aws4_request
サンプルリクエストでは、下記の値を使用し作成します。
日付 | 20221026 |
リージョン | east-1 |
サービス識別子 | rdb |
上記の例のほかに、利用可能リージョンやバージョン 4を利用可能なサービスは、下記ページを確認してください。
サンプルリクエストのCredentialScope
20221026/east-1/rdb/aws4_request
ヘッダーは、 サービスごとに指定できるパラメーター名が異なります。以下対応表を参考にしてください。
サービス識別子 | service-activity | s3 | nas | rdb | ||
---|---|---|---|---|---|---|
リクエスト日時/ シグネチャーの暗号方式/ CredentialScope末尾の文字列 |
X-Amz-Date/ AWS4-HMAC-SHA256/ aws4_request | ○ | ○ | ○ | ○ | ○ |
X-Nifty-Date/ NIFTY4-HMAC-SHA256/ nifty4_request | × | × | ○ | ○ | × |
Hash(CanonicalRequest)
手順1の7番目で作成した正規化リクエストを、ペイロードをハッシュ化した際と同じ手法でハッシュ化した値です。
サンプルリクエストのHash(CanonicalRequest):
fc8bf674f978935a6c641202356c1105d10b334c467cbe43c5fb8cab9e0551fe
署名文字列の作成
下記の署名文字列を使用して、次の手順でシグネチャーを生成します。
サンプルリクエストの署名文字列:
AWS4-HMAC-SHA256\n
20221026T014354Z\n
20221026/east-1/rdb/aws4_request\n
fc8bf674f978935a6c641202356c1105d10b334c467cbe43c5fb8cab9e0551fe
署名キーの作成
シグネチャー 4では、「シークレットアクセスキー」ではなく「シークレットアクセスキーから引き出したキー(署名キー)」を使って署名します。
シグネチャーを算出するために、まずはシークレットアクセスキーから署名キー(kSigning)を作成します。
※サンプルリクエストでは、サンプルリクエスト・認証情報に記載したシークレットアクセスキーを使用します。
署名キーの作成方法
kSecret = シークレットアクセスキー
kDate = HMAC("AWS4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "aws4_request")
HMAC(key、data)は、HMAC-SHA256によるハッシュ化機能を示しています。
HMACでハッシュ化する関数やメソッドが、各種プログラミング言語で提供されています。サンプルリクエストでは、下記の通りです。
kSecret =1234567890abcdefghijklmnopqrstuvwxyzABCD
Date = 20221026
Region =east-1
Service = rdb
上記を使用し先述の方法に従って作成すると、下記の値になります。
サンプルリクエストの署名キー:
ece81671ab267ce4dc6b81d5f0018d3173ca05a43d18aae37935d0a88f495be7
※ 署名キーを16進数で出力した結果です。
3. シグネチャーを生成
作成した署名キーを使用してシグネチャーを生成します。シグネチャーの生成方法は下記の通りです。
シグネチャーの生成方法
signature = HexEncode(HMAC(署名key, 署名文字列))
※ 署名キーは先述のサンプルに示した16進数表示の値ではなく、kSigning の生の値を利用します。
HMACでハッシュ化した値を16進数エンコードします。
サンプルリクエストに対して上記処理を実行すると下記の値となり、認証に使用できます。
サンプルリクエストのシグネチャー:
678cf1a18fd9b55056131bf1611080d6d6fede2ba98c8fd35626edc8e87c62ff
リクエスト送信例
生成したシグネチャーと、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-Amz-Date」と「Authorization」です。
Authorizationパラメーターは下記テンプレートに従い、ハッシュ化アルゴリズム、アクセスキー、シグネチャーを設定します。
Authorization:<ハッシュ化アルゴリズム>
Credential=<アクセスキー>/<CredentialScope>,
SignedHeaders=<SignedHeaders>, Signature=<シグネチャー>
上記テンプレートに従ったサンプルリクエストの「Authorization」を、下記に示します。
Authorization:AWS4-HMAC-SHA256
Credential=12345678901234567890/20221026/east-1/rdb/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=678cf1a18fd9b55056131bf1611080d6d6fede2ba98c8fd35626edc8e87c62ff
以上の情報を組み合わせると、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-amz-date:20221026T014354Z' \
--header 'Authorization:AWS4-HMAC-SHA256
Credential=12345678901234567890/20221026/east-1/rdb/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=678cf1a18fd9b55056131bf1611080d6d6fede2ba98c8fd35626edc8e87c62ff'
フィードバック
サービス利用中のトラブルは、ニフクラサポート窓口にお願いします。
お役に立ちましたか?