HMAC - Wikipedia
http://ja.wikipedia.org/wiki/HMAC
RFC2104 - HMAC: Keyed-Hashing for Message Authentication
http://tools.ietf.org/html/rfc2104
要するに、データをキーでハッシュします。これによりデータを認証できます。
Perlで簡単に実装できるのでやってみた。
OAuthのためのBase64エンコードについても少し触れています。
use Digest::SHA1; use Digest::MD5; sub hmac{ my ($object, $key, $msg) = @_; # init if(length($key) > 64){ $key = $object->add($key)->digest; $object->reset(); } # calc $msg = $object->add($key ^ "\x36" x 64, $msg)->digest; $object->reset(); # return return $object->add($key ^ "\x5C" x 64, $msg); } my $key = "Jefe"; my $msg = "what do ya want for nothing?"; print hmac(new Digest::MD5, $key, $msg)->hexdigest . "\n"; # HMAC-MD5 : Hex print hmac(new Digest::SHA1, $key, $msg)->b64digest . '=' . "\n"; # HMAC-SHA1 : Base64
750c783e6ab0b503eaa86e310a5db738
7/zfauXrL6LSdBbV8YTfnCWafHk=
HMACは様々なハッシュに対応できるので、それを生かすためにこんな実装にしてみました。
new, reset, add, digestメソッドが備わったモジュールであれば何でも使えます(Digest::MD5などの実装に習った実装であれば、ですが)。
Outputされるのは1つ目の例はHMAC-MD5で16進数文字列で出力、2つ目の例はHMAC-SHA1でBase64エンコードで出力しています。
HMAC-SHA1はOAuth認証で使われていたりします。
OAuth認証ではBase64エンコードされたデータでやりとりするので、b64digestで変換します。
ここで大事なのは、'='を1個つける事です。
理由を以下で説明します。
Base64エンコードは6bitを8bitで表現する符号化です。
また、Byte数が4の倍数になるように、'='で調整することになっています。
つまり、Base64に変換したときの情報量の変化は4/3倍+1〜3byteになります。
一方、SHA1で得られるハッシュは160bitで固定です。
このハッシュをBase64エンコードを行うと、データ量は以下になります。
160bit * 4/3 / 8bit = 26.625byte ≒ 27byte
4の倍数になるように調整するので、'='を1個加えて、28byteとなります。
SHA1の演算結果は固定なので、わざわざ長さを求めて'='を何個くわえるか、といった処理はする必要はないです。
もちろん使うDigestアルゴリズムが定まってない場合は必要です。
Perlであれば以下の感じで4の倍数になるように'='を連結させる事ができます。
$digest .= ('=' x (3-(length($digest)+3)%4) );