2024-03-05 鍵導出関数がほしいなと思って、昨日 Wikipedia の PBKDF2 の記事を読んでいた。 記事の「HMACの衝突」セクションに、興味深い記述があった。 HMAC-SHA1 を用いた PBKDF2 で、同じ鍵が得られる 2 つのパスワードが書かれている。 これは SHA1 に限らず、どんな HMAC でも発生させられる事象らしい。 衝突についての出典として書かれているリンクが事象の理解に役立った。 「脆弱性を示唆するものではない」のリンクはこの件と関係ない話に見えた。 ここから導き出した私の結論は、こうだ: * パスワードや共有鍵は、そのハッシュ値を公開することに危険を伴う場合がある (わたしは、鍵とハッシュ関数の両方が十分強力なら、通常危険はないと思っていた) * HMAC は RFC2104 の通りに使うべきではない。 アプリケーションは、鍵に前処理 (後述) をしてから使うべきだ。 かんたんに言うと、これは HMAC が鍵に行う前処理の特性によるものだ。 HMAC のアルゴリズムの核となる部分は、 使われる鍵が一定以下の長さであることを求めている。 そのため、鍵がそれより長いと、先に鍵をハッシュ化するのだ。 一方、鍵が十分に短い場合はこの処理は行われない。 RFCの記述を引用すると、こうだ。 > Applications that use keys longer than B bytes will first hash the key using > H and then use the resultant L byte string as the actual key to HMAC. だから、長い鍵を使って生成する HMAC は、 その鍵をハッシュ化したものを使って生成する HMAC と同じ値になる。 Wikipedia の記述は、これを問題ないとしている。 本当にそうだろうか? 十分に注意深くすべてが管理されているなら、実際これは問題にならないだろう。 しかし、これは誤りのもとに見える。 一般に、(暗号論的)ハッシュ関数が生成する値は、 もとのメッセージが持つ意味を読み取れないものであると期待されるだろう。 私が言っているのは、「私はいつも夕ごはんにおみおつけを食べます」という文の ハッシュが「夕食に味噌汁を飲むのは僕の日課だ」という文ではいけないということだ。 後者から前者を復元するのは(そこそこ)難しいが、2つの文の意味はほぼ同じで、 日本語の世界では 2 つの文は同様に機能してしまう。 ハッシュが元の文と同様の意味を持ってはいけないのだから、 HMAC の実装はまずいものだ。 「HMAC の鍵」という言語は、自身が使うハッシュ関数を劣ったものにしてしまうのだ。 具体的にまずいことが起こる例を挙げよう。 あるサービスが認証にパスワードを利用するとする。 そのサービスでは、パスワードを PBKDF2 でハッシュ化して保存することにした。 認証を要求するユーザは自身のパスワードをサービスに伝え、 サービスはその PBKDF2 を計算して保存されたハッシュと比較する。 そのサービスの利用者の一人が、とても優れた乱雑なパスワードを使っていたとする。 彼のパスワードは 256bit くらいの乱雑さを持っており、 総当り攻撃で当てるのはほぼ不可能だ。 しかし代わりに、彼のパスワードはとても長く、 PBKDF2 に利用された HMAC は 先にこれを H でハッシュ化してから扱う。 彼は自身のパスワードの頑強さとハッシュ関数 H の信頼性を確信しており、 パスワードのハッシュを公開してしまった。 彼のパスワードのハッシュを知った人は、 パスワードの代わりにハッシュを打ち込んで彼になりすますことができる。 ここで悪いのは HMAC だろうか。パスワードのハッシュを公開した人物だろうか。 パスワードのハッシュを公開することはあまり優れた行いではないだろうが、 十分乱雑なパスワードと頑強なハッシュ関数を使うなら、通常問題ないはずだ。 ... そのハッシュ関数が HMAC に使われない限り。 そんなわけで、 HMAC を使うアプリケーションは、 不幸が起きないように鍵に前処理をするべきだ。 具体的に、このような前処理がこの問題の解決に十分役立つだろう: 鍵にアプリケーション固有の固定文字列をつなげ、ハッシュ化する。 アプリケーション固有の文字列は、適当な乱数列とかを使うのが良いだろう。 HMAC と別にハッシュ関数を用意するのが面倒な場合、次の処理でも良いだろう: 1. 鍵にアプリケーション固有の固定文字列をつなげる 2. 鍵が HMAC のハッシュ長 B より長くなるように文字 '0' を末尾に付加する 「アプリケーション固有の固定文字列」は '0' 以外の文字を含む必要がある。 と、そんなことを考えてここに書き出したわけだが、 そういう主張をしている人は他に居ないのだろうか。今更気になった。 2024-03-06 普通に errata があった