UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Authorization】JavaScriptでHMAC-SHA512を使ったメッセージ認証コードの生成

とあるAPIで 次のようなメッセージ認証を行うサービスがあった

  1. 次の値を\n区切りで結合した文字列にする
    • HTTPリクエストメソッド (GET or POST)
    • URLのパス (e.g. /path/to/api/{id})
    • クエリパラメータ (e.g. targets=default).
    • 送信リクエストのUTCタイムスタンプ(ISO-8601 datetime format: yyyy-mm-ddThh:mm:ssZ)
    • リクエスト本文のSHA-512ハッシュ化した値
  2. 1.をSHA-512ハッシュ化する
  3. 鍵とHMAC-SHA512を使って2.の認証コードを生成する
  4. AuthorizationヘッダーにHMAC-SHA512と3.で生成されたHMAC署名を指定する

これをJavaScriptで実装したい

SHA-512HMAC-SHA512の部分をどうしようかと思ったが、次のnpmモジュールを見つけたのでこれを使う

js-sha512 - npm

1.の部分

const sha512 = require("js-sha512").sha512;

const endpoint = "https://endpoint/path/to/api/12345";
const url = new URL(endpoint);
const requestMethod = "GET"; 
const timestamp = new Date(new Date().toUTCString()).toISOString();
const key = "abcdefghijklmnopqrstuvwxyz";
const requestBody = "aaaaaaaaa";
const path = url.pathname;
const query = url.search.slice(1);
const hashedBody = sha512(requestBody);
const requestData = [requestMethod, path, query, timestamp, hashedBody].join("\n");

2.の部分

const hashedRequest = sha512(requestData);

3.の部分

const sig = sha512.hmac(key, hashedRequest);

4.の部分

const authHeader = `HMAC-SHA512 signature=${sig}`;

axios
  .get(endpoint, {
    headers: {
      Authorization: authHeader,
    },
  })

HMAC-SHA512の部分を実装する必要があるかと思ったが、とりあえずこのライブラリでいけたのでこのまま使う