HMAC-SHA256を計算し結果をbase64エンコード

広告

ここまでのページで署名の対象となる文字列を作成しました。この文字列をHMAC-SHA256で計算します。この値はまったく分からなかったので、下記のサイトを参考にさせて頂きました。

Amazon Product Advertising APIの認証をJavaScriptで

まず下記のサイトで配布されている「jssha256」をダウンロードします。

jssha256: SHA256 & HMAC-SHA256 in JavaScript

HMAC-SHA256を計算し結果をbase64エンコード

HMAC-SHA256を計算し結果をbase64エンコード

開いたページを少し下へスクロールして頂くと上記赤い四角で囲まれた位置に「jssha256-0.1.tar.gz」と書かれたリンクが有りますのでクリックしてダウンロードして下さい。ダウンロードしたファイルを解凍すると「jssha256.js」というJavaScriptが記載されたファイルが1つ含まれています。

続いて下記のサイトで配布されている「base64.js」をダウンロードします。

javascript - Yet Another Base64 transcoder

HMAC-SHA256を計算し結果をbase64エンコード

上記の「/lang/javascript/Base64/trunk - CodeRepos::Share - Trac」をクリックして下さい。

HMAC-SHA256を計算し結果をbase64エンコード

上記の「base64.js」をクリックして下さい。

HMAC-SHA256を計算し結果をbase64エンコード

開いたページを一番最後までスクロールして下さい。そして「Original Format」をクリックして頂くとファイルをダウンロードします。ダウンロードした「base64.js」ファイルもJavaScriptが記載されたファイルです。

この2つのファイルを適当な位置に設置し、利用するHTMLページから読み込んでおきます。(詳しくは後のサンプルを見てください)。

計算

では前のページまでで作成した文字列をHMAC-SHA256で計算します。

...

var str_signature = "GET" + "¥n" + "webservices.amazon.com" + "¥n" + "/onca/xml" + "¥n" + str_para;

HMAC_SHA256_init("1234567890");
HMAC_SHA256_write(str_signature);
var array_hash = HMAC_SHA256_finalize();

var str_hash = "";
for (var i = 0; i < array_hash.length; i++) {
  str_hash += String.fromCharCode(array_hash[i]);
}

ここでダミーの秘密キー「1234567890」を使用しています。実際に使う場合には本当の秘密キーを使用して下さい。

続いてbase64エンコードを行います。

...

var str_signature = "GET" + "¥n" + "webservices.amazon.com" + "¥n" + "/onca/xml" + "¥n" + str_para;

HMAC_SHA256_init("1234567890");
HMAC_SHA256_write(str_signature);
var array_hash = HMAC_SHA256_finalize();

var str_hash = "";
for (var i = 0; i < array_hash.length; i++) {
  str_hash += String.fromCharCode(array_hash[i]);
}

var signature = Base64.encode(str_hash);

これで署名が作成できました。

サンプル

では簡単なサンプルで試してみます。

sample5_1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>署名認証テスト</title>
<script type="text/javascript" src="./js/jssha256.js"></script>
<script type="text/javascript" src="./js/base64.js"></script>
<script type="text/javascript" src="./js/script5_1.js"></script>
</head>
<body>

<p>
ボタンを押して下さい
</p>

<p>
<input type="button" name="checkbutton" value="check" onclick="getSignature()" />
</p>

<div id="output" style="width: 500px; height: 100px"></div>

</body>
</html>

script5_1.js

function getSignature(){
  var para = {
    "Service":"AWSECommerceService",
    "AWSAccessKeyId":"00000000000000000000",
    "Operation":"ItemLookup",
    "ItemId":"0679722769",
    "ResponseGroup":"ItemAttributes,Offers,Images,Reviews",
    "Version":"2009-01-06",
    "Timestamp":"2009-01-01T12:00:00Z"
  };

  var para_array = [];

  for(var pname in para){
    para_array.push(pname + "=" + encodeURIComponent(para[pname]));
  }

  para_array.sort();

  var str_para = para_array.join('&');
  var str_signature = "GET" + "¥n" + "webservices.amazon.com" + "¥n" + "/onca/xml" + "¥n" + str_para;

  HMAC_SHA256_init("1234567890");
  HMAC_SHA256_write(str_signature);
  var array_hash = HMAC_SHA256_finalize();

  var str_hash = "";
  for (var i = 0; i < array_hash.length; i++) {
    str_hash += String.fromCharCode(array_hash[i]);
  }

  var signature = Base64.encode(str_hash);

  var html = "<p>署名 : " + signature + "</p>";
  document.getElementById('output').innerHTML = html;
}

上記を実際にブラウザ見てみると次のように表示されます。

署名対象のリクエスト文字列

ボタンを押すと次のように表示されます。

署名対象のリクエスト文字列

ここで表示された署名はAmazonの「サンプルリクエストに署名を行うためのステップ」で表示されている署名と一致します。その為、ここまでの処理は問題無いのではと思われます。

( Written by Tatsuo Ikura )