web-dev-qa-db-ja.com

塩漬けハッシュ対HMAC?

アクセス資格情報に関する議論のほとんどには、「ソルトされたパスワードのハッシュ」への言及が含まれています。これは、HMACアルゴリズムを参照する別の方法ですか、それともまったく異なる操作ですか?異なるかどうかにかかわらず、これは公開された標準-FIPS198を簡単に参照できるので、なぜHMACを使用しないのですか?

33
Drew Lex

HMACは Message Authentication Code であり、integrityを検証するためのものです。これはまったく違う種類の獣です。

ただし、HMACはハッシュ関数を基に構築されており、「キー付きハッシュ」、つまりkeyを含むハッシュ関数と見なすことができます。鍵はソルトではありません(鍵は秘密ですが、ソルトはそうではありません)。しかし、HMACの固有の特性により、HMACは他の関数の妥当な構築ブロックになります。これは PBKDF2 で発生するものです。これは、一般にパスワードハッシュに変換されるキー導出関数です(適切と思われる役割)。 PBKDF2にはsaltが含まれ、内部でHMACを呼び出します(数回)。

適切なパスワードハッシュはslow(構成可能な方法で)であり、salt。これらの特性は簡単に取得できず、単独のHMAC(高速でソルトを使用しない)からは取得できません。

36
Thomas Pornin

簡潔な答え:

ちょっとですが、実際にはそうではありません。ソルトは、ハッシュされる前にメッセージに追加される単純なランダムなデータであり、ソルトされたメッセージによって生成されるハッシュを、攻撃者が同じであるが無塩のメッセージ(または他の任意のメッセージ)を使用してすでに計算したものとは異なるものにするという目的があります。塩、そのことについては)。通常、オンデマンドで秘密のメッセージの正しいハッシュを合法的に計算するために、saltは公開されている必要があります。改ざん防止の認証済みハッシュを生成する公開メッセージの「秘密の塩」は理論的には機能しますが、実際には私たちのハッシュ関数は不完全であり、このように使用すると、元のメッセージにデータを追加する攻撃に対して脆弱になりますそして、予測可能な方法でハッシュを変更します(「長さ拡張攻撃」)。

HMACには、追加の秘密データが鍵の形で組み込まれています。このキーは、ソルトよりもはるかに深い方法でメッセージと組み合わされ、メッセージの単純なソルトに加えて使用できます。最終結果は、秘密のソルトを使用した単純なハッシュと同じ攻撃に対して脆弱ではなく、認証されたハッシュを生成するためのはるかに強力な方法になります。

より長い答え:

ハッシュ、つまりハッシュの基本的な目的は、「ランダムなOracle」をエミュレートすることです。 messageを指定できる概念的なブラックボックスであり、真にランダムで真に一意のdigest値を生成して識別し、与えられた場合に同じランダムな値を生成します。同じメッセージ。多くの暗号アプリケーションでこのタイプの機能が必要であり、すべてランダムにOracleを微妙に異なる方法で使用します。残念ながら、真のランダムなオラクルは存在しないため、既知の固有の弱点を持つハッシュ関数で十分でなければなりません。

「ハッシュ化されたソルトパスワード」は1つの用途です。メッセージ(パスワード)は秘密であるという考え方です。ハッシュされた値により、システムが実際のパスワードを記憶しなくても(脆弱にするため)、誰かがシステムに正しいパスワードを知っていることを証明できます。理論的には、ランダムなOracleにメッセージを与えて、本当に一意の値を返すだけで十分ですが、ランダムなOracleはなく、代わりにハッシュ関数を使用する必要があるため、可能なダイジェスト値の数はハッシュ関数です。生成できるのは有限なので、理論的には、目的のハッシュを生成するメッセージ、メッセージを見つけ、それらすべてを覚えておけば、観測されたハッシュを検索して、それを生成するメッセージを見つけることができます。ソルトは、メッセージの正しい組み合わせがあることを保証するために、可能性のあるすべてのソルトで可能なすべてのメッセージのハッシュを計算することを攻撃者に要求することにより、この理論をはるかに困難にしますand saltで観測されたハッシュを生成します。秘密のメッセージを正当にハッシュする場合は正しいソルトを使用する必要があるため、ソルト値は公開情報である必要があります。これは、スキームのセキュリティを確保するために秘密にしておかなければならないキーとは異なります。

ただし、トーマスによるパスワードハッシュの観察は非常に正しいものです。ユーザーが選択したパスワードは本質的にエントロピーが低いため、ソルト処理されている場合でも、ブルートフォースで比較的簡単に推測できます。これを防ぐには、追加のセキュリティが必要です。これは通常、「キーストレッチ」の形で提供されます。計算コストの高い変換が追加され、1つのハッシュの生成が遅くなります(正当なユーザーに影響を与えるほど遅くはありません)。各ハッシュに追加された作業により、ハッシュ計算を数十万回繰り返すことにより、パスワードをブルートフォースで強制することが攻撃者にとって容認できない状況になります。この処理をオンデマンドで実行するのを避ける最も簡単な方法は、「より高速な」ハッシュアルゴリズムのように、事前に実行して結果を覚えておくことなので、ソルティングが依然として必要です。

HMACの目的は微妙に異なります。メッセージはnotが秘密かもしれないという考えです。したがって、基本的なハッシュが使用された場合、noシークレットが含まれる可能性があります。これは前代未聞の状況ではありません。ファイルのチェックサムは、それらを生成するために使用されるファイルと同様に自由に利用できますが、チェックサムハッシュは通常、変更から保護されています。ただし、ダイジェストが「読み取り専用」であることが保証できない場合、たとえばメッセージとともに送信された場合、ハッシュは、送信されたメッセージと一致するように変更されるため、値がありません。シークレットをプロセスに再度追加して、シークレットを知っている人だけがメッセージ(またはanyメッセージ)を使用して一致するハッシュを生成できるようにする必要があります。 HMACは、メッセージ(ソルトが可能)とキーを組み合わせて、そのような秘密を提供します。

さて、salt値を単純にキーとして秘密にしておくことができず、プリミティブなセキュアハッシュ関数でハッシュする前にメッセージに連結できないのはなぜでしょうか。その答えは、「ランダムなオラクルはありません」というポイントに結びついています。ランダムなOracleがあった場合、メッセージの一部を秘密にしておくことができます。正確な秘密と再結合しない限り、メッセージの残りの部分を指定しても、Oracleが同じ値(または予測可能な値)を生成することはありません。差し控えた。ただし、実際の「安全な」ハッシュ関数のほとんどには、「長さ拡張」と呼ばれる攻撃を可能にする既知の脆弱性があります。任意の長さのハッシュダイジェストとそれを生成したハッシュプリミティブの知識が与えられた場合、多くの場合、元のメッセージ全体を知らなくても、既知のデータをメッセージの末尾に追加することに対応する変更されたハッシュを生成することができます(私たちの場合、これには連結またはXORされた「秘密の塩」が含まれます。 HMACは、ネストされたハッシュ操作でキーとメッセージを複数回結合することによりこれを無効にするように特別に設計されており、その結果、長さ拡張を簡単に実行できないダイジェストが生成されます。

25
KeithS