自分が実装担当な所は Java なのだが、外注さんにお願いしているパートが PHP で書かれていて、
お互いに HMAC-SHA256 で認証しようとしているのだが、外注さんが俺が渡した Javascript によるサンプルと、
適当にネットでみつけた PHP のそれっぽい関数のドキュメントだけでは難儀しているようだったので、
ちょっと見てみた。
ぶっちゃけ俺は PHP さっぱりなのだが、つまりはこうすればいいのですよという答。
<html> <head> <title>RFC 4868 Test cases in PHP</title> </head> <body> <tt> <?php // 文字列を16進数として解釈し、その値が示す文字列にする。 // (ちゃんとした PHP 使いならもう少しまともに書けるのかもしれないが、とりあえず動く版) function hex2str($hexString) { $what = pack("H*", $hexString); //var_dump($what); $arr = unpack("C*", $what); $result = ""; $lengthOfArr = count($arr); for ($i = 1; $i <= $lengthOfArr; $i += 1) { $result .= pack('C*', $arr[$i]); } return $result; } // RFC 4868 Test case 1 echo "RFC 4868 Test case 1<br />"; $message = "Hi There"; $secret = hex2str("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7<br /><br />"; // RFC 4868 Test case 2 echo "RFC 4868 Test case 2<br />"; $message = "what do ya want for nothing?"; $secret = "Jefe"; echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843<br /><br />"; // RFC 4868 Test case 3 echo "RFC 4868 Test case 3<br />"; $message = hex2str("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"); $secret = hex2str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe<br /><br />"; // RFC 4868 Test case 4 echo "RFC 4868 Test case 4<br />"; $message = hex2str("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"); $secret = hex2str("0102030405060708090a0b0c0d0e0f10111213141516171819"); echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b<br /><br />"; // RFC 4868 Test case 5 echo "RFC 4868 Test case 5<br />"; $message = "Test Using Larger Than Block-Size Key - Hash Key First"; $secret = hex2str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54<br /><br />"; // RFC 4868 Test case 6 echo "RFC 4868 Test case 6<br />"; $message = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm."; $secret = hex2str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); echo " result:" . hash_hmac("sha256", $message, $secret) . "<br />"; echo "expected:9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2<br /><br />"; ?> </tt> </body> </html>
なんかネットで軽く検索してもそれっぽい物が全然ひっかからないんだよなぁ。なんでだろ。
とりあえずここまでの俺の PHP に対する理解(間違ってるかも)。
・バイナリデータを扱う方法は整数の配列か文字列の二択がありそう。
・文字列は多分、入力値のチェックとかしてなくて、生のバイト配列に毛がはえた程度と思っても良いのかも(要確認)。
・PERL から PHP が引き継いだと思われる pack/unpack は上記あたりの処理をするのに鬼門なのかも。