16進数文字列をバイナリデータにパックしてHMAC を算出するワンライナー


背景

諸事情により、HMAC-MD5 を大量に作成するアドホックなタスクが発生した。
アドホックな大量タスクをこなすにはワンライナーを使うのが一番なので HMACの算出をするワンライナーをさがしたが、ワンライナーが苦手な一時ファイル作成をせずに任意のバイナリを入力可能な方法が意外と一般的ではないようだったので、後学のためにここに記録しておく。

やり方

key='ほげ' value='ふが'; echo -n "$value" | xxd -r -p | openssl dgst -md5 -mac HMAC -macopt "hexkey:$key"

ほげふがにはバイナリを16進数にした文字列を指定する。
キモとなるのが openssl の hexkey という引数で、これが使えるようになったのは比較的最近のようだ。(0.9.8 ではだめで、1.0.2 なら大丈夫だった)

参照

OpenSSL HMACコマンドの使い方(dgst -hmacの引数がひどい件) | Engineer's Notebook http://myenotes.blog.fc2.com/blog-entry-107.html
opensslのHMACコマンドではまった話 http://homepage1.nifty.com/herumi/diary/1207.html

検証

RFC 2104 の Sample Code に書かれている内容と一致するかを確認する。
https://tools.ietf.org/html/rfc2104
openssl を絶対パス指定しているのは、実行環境にインストールされている古いopenssl を使わないため。

A

key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
key_len =     16 bytes
data =        "Hi There"
data_len =    8  bytes
digest =      0x9294727a3638bb1c13f48ef8158bfc9d

一致

% key='0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b' value=`echo -n 'Hi There' | hexdump -e '1/1 "%02x"'`;  echo -n "$value" | xxd -r -p | /usr/local/Cellar/openssl/1.0.2h_1/bin/openssl dgst -md5 -mac HMAC -macopt hexkey:$key
(stdin)= 9294727a3638bb1c13f48ef8158bfc9d

B

key =         "Jefe"
data =        "what do ya want for nothing?"
data_len =    28 bytes
digest =      0x750c783e6ab0b503eaa86e310a5db738

一致

% key=`echo -n 'Jefe' | hexdump -e '1/1 "%02x"'` value=`echo -n 'what do ya want for nothing?' | hexdump -e '1/1 "%02x"'`; echo -n "$value" | xxd -r -p | /usr/local/Cellar/openssl/1.0.2h_1/bin/openssl dgst -md5 -mac HMAC -macopt hexkey:$key
(stdin)= 750c783e6ab0b503eaa86e310a5db738

ちなみに

HMAC-SHA256 が欲しい場合は dgst -md5dgst -sha256 にすればOK

関連ページ

情報ソース