ハッシュアルゴリズムを「安全」にするものは何ですか?


19

この興味深い質問を読んだ後、必要な場合にどの安全でないハッシュアルゴリズムを使用するかについて良いアイデアがあると感じましたが、代わりに安全なアルゴリズムを使用する理由はわかりません。

それで、違いは何ですか?出力はハッシュされたものを表す単なる乱数ではありませんか?一部のハッシュアルゴリズムを安全にする理由は何ですか?


8
この質問は、IT Security SEサイトにより適しています。
バーナード

@Bernardその場合、私はそれでいいのですが、私の質問は安全なハッシュをどのように、いつ使用するかではなく、安全なハッシュアルゴリズムと安全でないハッシュアルゴリズムを区別するものではありません。それは私にとってプログラミングの質問のように思えますが、IT Security SEをブラウズしていないので、そこでもうまくいくかもしれません。
CodexArcanum

2
非常によく似た質問がITセキュリティについて既に質問されています
ChrisF

回答:


34

すべての暗号化ハッシュ関数に必要な3つのプロパティがありますH

  • プレイメージ抵抗:考えるとh、任意の値を見つけるのは難しいべきであるxとしh = H(x)

  • 第2のプレイメージ抵抗:与えられてx1、それで見つけるのx2 != x1は難しいはずH(x1) = H(x2)です。

  • 衝突抵抗:それは2つの値を見つけるのは困難であるべきx1 != x2H(x1) = H(x2)

(文字列の)ハッシュテーブル用の一般的なプログラミング言語で使用されるハッシュ関数では、通常これらのいずれも提供されず、次の機能のみを提供します。

  • 弱い衝突抵抗:ドメインのランダムに(または「通常」)選択された値の場合、衝突の可能性はわずかです。これは、攻撃者が意図的に衝突を作ろうとしたり、プリイメージを見つけようとしたりすることについては何も言いません。

上記の3つのプロパティは、(すべての)暗号化ハッシュ関数の設計目標です。一部の機能(MD4、SHA-0、MD5など)では、これが(少なくとも部分的に)失敗したことがわかっています。現在の世代(SHA-2)は安全であると想定されており、次の世代(「Secure Hash Algorithm 3」)は現在、競争の標準化の過程にあります。

一部の用途(パスワードハッシュやパスワードからのキー派生など)では、実際に使用される値のドメインxが非常に小さいため、通常の(高速)セキュアハッシュ関数を使用してこのスペースを総当たり攻撃することが可能になります。

  • 遅い実行:与えられたx、それは値を計算するためにリソースのいくつかの最小(できれば設定可能)量がかかりますH(x)

しかし、他のほとんどの用途では、これは望ましくありません。

  • 高速実行:指定xされたの値の計算はH(x)、可能な限り高速です(ただし、安全です)。

頻繁に反復することにより、高速ハッシュ関数から低速ハッシュ関数を作成する構造(PBKDF2やscryptなど)があります。

詳細については、姉妹サイトのCryptography Stack Exchangeのハッシュタグをご覧ください。


3

セキュアとは、衝突(つまり、2つのソースが同じ値にハッシュされているという事実)を使用してエラーを引き起こそうとしている人が困難になることを意味します。

いくつかの特徴:

  • ハッシュを知って、その値にハッシュするファイルを作成するのは困難です(バリアント、新しいファイルの一部と、目的のハッシュが与えられます)

  • 同じ値にハッシュする2つの異なるファイルを作成することは困難です(バリアント、ファイルの一部が指定されています)


3

主な違いは非常に単純です。通常のハッシュは、プロセス全体の速度を落とすことなくできる範囲で、偶発的な衝突の数を最小限に抑えることを目的としています。

誰かが衝突を引き起こすために最善を尽くしている場合でも、衝突を防ぐことを目的とした安全なハッシュ。あなたは、一般的に取引したくない任意の高速化のための衝突の可能性を。実際、操作を意図的に遅くすることは、たとえ衝突を見つけにくくしなくても、それ自体にいくつかのセキュリティ上の利点があります。

後者の例:ハッシュの計算に50ミリ秒かかる場合、通常のユーザーのログインに重大な影響はありません(つまり、ほとんどのユーザーはログイン時に50ミリ秒の違いに気付きません)。同時に、攻撃者が辞書攻撃を行いたい場合、1秒あたり20ハッシュしか生成できないことは深刻なハンディキャップです。言い換えれば、何らかの理由で、安全なハッシュのためには、遅い方が良いです。


3
暗号化ハッシュ関数のドメインには、2つの重要なサブグループがあります。高速サブグループ(メッセージ認証、署名などに使用)、および低速サブグループ-キー派生とパスワードハッシュに使用されます。これらを混在させないでください、両方にアプリケーションがあります。
パエロエベルマン

実際には、衝突を最大化するように設計されたハッシュ関数もあります。Soundexはその一例です。明らかに、これは非常に安っぽい安全なハッシュ関数になります。
ヨルグWミットタグ

@JörgWMittag:安全なハッシュとして安っぽいだけでなく、ハッシュテーブルでの使用には非常に貧弱です。繰り返しますが、確かにある程度ハッシュに似ていますが、Soundexをハッシュ関数と呼ぶのをためらうでしょう。その目的と使用法が通常のハッシュ関数とはまったく異なるからです。
ジェリーCo

@JerryCoffin:定義に依存すると思います。たとえば、英語版ウィキペディアのページでは、ハッシュ関数とは、任意の値のより大きな(潜在的に無限の)セットを、より小さな有限の(通常はスカラー)値のセットにマッピングするアルゴリズムまたはサブルーチンであると述べています。ドイツのウィキペディアのページでは、「ハッシング」(ドイツ語:「zerhacken」)は不可欠な部分であると言われています。つまり、マップされた値の衝突回避と分布が重要です。Soundexは最初の定義を非常に満たしますが、2番目の定義は満たしません。
ヨルグWミットタグ

3

このhttp://www.codinghorror.com/blog/2012/04/speed-hashing.htmlを読んでください。これは、私が説明することができなかったすべてのことをはるかによく説明します。質問に直接対処する記事の2つの最も重要なヘッダーを次に示します。

  • 安全なハッシュは改ざんされないように設計されています
    • 入力データへのわずかな単一ビット変更で出力を根本的に変更します
  • セキュアハッシュは低速になるように設計されています

最後の彼のTL; DRセクション:

あなたがユーザーの場合:

すべてのパスワードが12文字以上、理想的にはそれ以上であることを確認してください。パスフレーズを採用することをお勧めします。パスフレーズは、パスワード(入力しない場合)よりも覚えやすいだけでなく、純粋に長さのためにブルートフォースに対して途方もなく安全です。

開発者の場合:

セキュリティで保護する必要があるものをハッシュするには、bcryptまたはPBKDF2のみを使用してください。これらの新しいハッシュは、GPUでの実装が困難になるように特別に設計されています。他の形式のハッシュは使用しないでください。他のほとんどすべての一般的なハッシュスキームは、毎年より速く、より並列で簡単にプログラミングできる汎用GPUの配列によるブルートフォーシングに対して脆弱です。


4
ジェフはここで2番目の点で間違っています...一部の用途(パスワードハッシュとパスワードからのキー派生など)では遅くしたい、他の用途(メッセージ認証、署名など)で高速(安全)にしたいハッシュ関数は良いです。
パエロエベルマン

あなたは正しいPaŭloです。ハッシュのパフォーマンスは、ハッシュの適用に依存します。ただし、低速ハッシュは高速ハッシュよりも常に安全です。高速ハッシュを使用する理由は、パフォーマンスのためにセキュリティを犠牲にしても大丈夫な場合です。
ネイト

2
@Nate「より安全」は常にあいまいですが、最も慈善的なアプリケーションの下でも、「遅いハッシュは常に速いハッシュよりも安全です」は間違いです。ハッシュの速度が無関係なアプリケーションがたくさんあります。
ジル 'SO-悪であるのをやめる

@Gilles例を挙げていただけますか?それは実際には私には本当のように聞こえますが、より詳細な情報が役立つでしょう。
ネイト

2
@Nateハッシュの最も明白なアプリケーションは、データの整合性を検証することです:セキュアであるが低帯域幅のチャネルでハッシュを送信し、安全でないチャネルで多分大きなペイロードを送信してから、受信したペイロードが期待どおりであることを確認しますハッシュ。ハッシュは、署名方法(整合性を検証するだけでなく、データの送信者も検証する)で際立っています。パスワードのハッシュはむしろ例外です。
ジル 'SO-悪であるのをやめる

2

「安全な」ハッシュとは、ハッシュの作成に使用されたメッセージを事前に知らなくても、定型的で再現可能な方法で「なりすまし」が難しいと考えられるハッシュです。その情報は一般に秘密であり、したがってハッシュの必要性があるため、これは認証での使用を目的としたハッシュ関数の優れた特性です。

メッセージM、ハッシュ関数hash()、およびハッシュ(M)によって生成されるハッシュ値H(ビットLの長さ)が与えられた場合、ハッシュは一般に「安全」と見なされます。O(2 L)時間:

  • hash()およびHを指定すると、Mが生成されます(プリイメージ耐性)
  • hash()とMを指定すると、hash(M 2)== Hとなるような異なるM 2が生成されます(弱い衝突抵抗)
  • hash()を指定すると、hash(M 1)== hash(M 2)となるようなM 1およびM 2が生成されます。(強い衝突抵抗)

さらに、「安全な」ハッシュは、2 Lコンピュータが現在のハードウェアを実行するための実行可能なステップ数ではありません。32ビット整数ハッシュは、21億の値しか持つことができません。プリイメージ攻撃(特定のハッシュHを生成するメッセージを見つける)には時間がかかりますが、多くのコンピューター、特にコード破りでチャーターされた政府機関の手にとっては実行不可能ではありません。さらに、ランダムメッセージとそのハッシュを作成して保存するアルゴリズムは、確率に従って、77,000件のメッセージだけを試行した後、新しいメッセージごとに重複ハッシュを見つけることに50%のショットを持ち、75%の確率でヒットしますわずか110,000後に複製します。64ビットハッシュでさえ、約50億の値のみを試した後でも、50%の確率で衝突します。これが、小さなハッシュに対する誕生日攻撃の力です。対照的に、十億の数字(1.5 * 10 34)。

暗号化ハッシュに対する実証された攻撃のほとんどは衝突攻撃であり、2 L時間未満で衝突メッセージを生成する能力を実証しました(ほとんどはまだ指数関数的な時間ですが、指数を半分に削減することで複雑さが大幅に軽減されます) 128ビットのように簡単に解決できる256ビットのハッシュ、64ビットのように簡単に解決できる128ビットなど)。

ハッシュサイズが小さいことに加えて、ハッシュを明らかに安全でないものにする他の要因は次のとおりです。

低作業-ハッシュテーブルで使用するため、または他の「チェックサム」タイプの目的で設計されたハッシュは、通常、計算的に安価になるように設計されています。これにより、ブルートフォース攻撃がはるかに簡単になります。

「スティッキーステート」-ハッシュ関数は、特定の追加バイトの入力が与えられたときに、これまでのすべての入力の現在のハッシュ値が変更されない入力パターンになりがちです。「スティッキー状態」があると、衝突を見つけやすくなります。「スティッキー状態」ハッシュを生成するメッセージを特定すると、ハッシュを「スティッキー状態」に保つ入力バイトを追加することにより、同じハッシュを持つ他のメッセージを生成するのは簡単です「。

拡散-メッセージの各入力バイトは、同等に複雑な方法でハッシュ値のバイトに分散される必要があります。特定のハッシュ関数は、ハッシュの特定のビットに予測可能な変更を作成します。これにより、衝突の作成が簡単になります。ハッシュを生成するメッセージが与えられた場合、予想どおりに変化するビットのみに影響する新しい値をメッセージに導入することにより、衝突を簡単に作成できます。


0

手元のタスクに適切なアルゴリズムを使用します。

CRCはエラーの検出/修正に使用されます。

SHA2などの暗号メッセージダイジェストは、暗号構造(デジタル署名、MAC、キー派生/パスワードハッシュ関数)およびセキュリティプロトコルの構成要素として使用されます。

ハッシュテーブル/辞書/マップでは、SipHashを使用します

安全でないハッシュアルゴリズムと呼ばれるものは、次のCVEエントリで証明されているように、ハッシュテーブル使用しないでください:CVE-2003-0364、CVE-2011-4461、CVE-2011-4838、CVE-2011-4885、CVE-2011- 4462、CVE-2011-4815、CVE-2012-0840、CVE-2012-5371、CVE-2012-5374、CVE-2012-5375

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.