Webリクエストをハッシュを使って認証する必要があったので覚え書き。条件はクライアントとサーバーの両者が共通の秘密鍵を保持していること。
例1: ユーザ名をハッシュ化してリクエストに付加する
ハッシュ関数としてsha1を使うと仮定する。ユーザ名をusername、秘密鍵をsecret_codeとすると、ハッシュは以下のように計算できる。
1 |
hash = sha1(username + secret_code) |
そうして得られたこのハッシュ値を以下のようにリクエストに付加する。
1 |
http://api.example.com/?username=<username値>&hash=<hash値> |
リクエストを受け取ったサーバー側では、リクエスト中のusernameと独自に保持する秘密鍵からハッシュ値を計算し、リクエストに付加されているハッシュ値と一致したら認証OKとする。
例2: パラメータを組み合わせてハッシュ化してリクエストに付加する
以下のようなパラメータ付きリクエストを想定する。
1 |
http://api.example.com/?param1=<param1値>&param2=<param2値> |
それぞれのパラメータはユーザ固有とし、リクエストにはユーザ名は付加しないものとする。すると、ハッシュは以下のように計算できる。
1 |
hash = sha1(param1 + param2 + secret_code) |
そうして得られたこのハッシュ値を以下のようにリクエストに付加する。
1 |
http://api.example.com/?param1=<param1値>&param2=<param2値>&hash=<hash文字列> |
最初の例と同様に、リクエストを受け取ったサーバーは独自に保持する秘密鍵からハッシュ値を計算し、リクエストに付加されているハッシュ値と一致するかどうか確認する。
補足事項
クライアント側とサーバー側でハッシュ計算方法が共通になりさえすれば、ハッシュ計算方法はアレンジしても問題ない。上の例ではリクエストに付加する値だけをハッシュの元値として使ったけど、URLの部分文字列(たとえば “param1=<param1値>¶m2=<param2値>”) をそのままハッシュの元値として使ってもかまわない。
sha1でバイナリのダイジェストを使いたい場合はbase64でエンコードしてからリクエストに追加すれば良い。
参考サイト
PHP: sha1 – Manual
http://php.net/manual/ja/function.sha1.php
sha1 — 文字列の sha1 ハッシュを計算する
PHP: base64_encode – Manual
http://php.net/manual/ja/function.base64-encode.php
base64_encode — MIME base64 方式でデータをエンコードする