web-dev-qa-db-ja.com

HMACのゼロパディング

RFC 2104のセクション2では、HMACで使用されるキーには、基礎となるハッシュアルゴリズムのブロック長までゼロバイトを埋め込む必要があると定義されています。ゼロバイトで終わるキーは最後のバイトがないキーと同じ結果を生成するため、これは潜在的なセキュリティの脆弱性ではありませんか?

次のPHPコードは例を示しています:

$key = "key";
$message = "message";
var_dump(hash_hmac("SHA256", $message, $key));
var_dump(hash_hmac("SHA256", $message, $key.chr(0x00)));

次の出力を生成します。

string(64) "6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a"
string(64) "6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a"

同じRFCのセクション3が最小の長さのキーを推奨していることを知っています。これにより、ある種のハッシュされたキー生成ステップと同様に、この問題が解消されます。しかし、これは潜在的な問題である可能性があるように思われますか、それとも私は過度に偏執的ですか?

7
KennethJ

いいえ、これはセキュリティ上の脆弱性ではありません。

HMACには、基になるハッシュアルゴリズムのブロックサイズのキーが必要です。一般に、基盤となるハッシュアルゴリズムのブロックサイズのキーを指定する必要があります。

このサイズのキーを提供するのを忘れた場合、2つのオプションがあります。最初のオプションは、HMACがハードで高速に失敗し、鍵のサイズが間違っていることを通知することです。 2番目のオプションは、HMACが単に正しいサイズのキーを提供するつもりであると想定しているが、そこにあるはずのすべての後続ゼロバイトを誤って省略したことです。

上記の2番目のオプションは、受け入れる入力では寛大であるが、生成する出力では厳格であるというポリシーに一致しています。

したがって、小さいサイズのキーは有効なキーではないため、HMACは2番目のオプションで情報を失うことはありません。無効なキーを取得して、何らかの方法で確定的に文書化された方法でそれらのキーを有効にするというポリシーがあります。

7
yfeldblum

HMACのようなアルゴリズムでは、キーの強度は、操作するために選択したセット内の可能なキーの数に関係します。たとえば、128ビットのキーを使用する場合、すべてのキーの長さがちょうど16バイトになります。

2つの異なるキーが同じHMAC動作を生成する可能性があるのは、システムで両方のキーが可能である場合にのみ潜在的な問題です。ここで話している問題については、これは、システムがさまざまな長さのキーを受け入れる場合にのみ発生することがありますが、これは一般的な状況ではありません。 SSL/TLS を検討する場合、HMACは、特定の固定の長さのマスターシークレットから生成されたキーで使用されます。特定のハッシュ関数(たとえば、SHA-256が使用されている場合、HMACキーは常に32バイトの長さになります)。したがって、問題ありません。

キーがC文字列(つまり、値0のバイトで終了する文字列)の場合、問題もありません:定義により、C文字列には値0のバイトが含まれないため、ゼロを介して2つの異なるC文字列を持つことはできません-パディング、同じキーを生成します。

本当に気が動転している場合、1つのオプションは、キーを体系的にハッシュし、そのハッシュ出力をHMACの実際のキーとして使用することです( HMAC仕様 は、キーが基礎となるハッシュ関数の「ブロックサイズ」より大きい)。

3
Tom Leek