この興味深い質問を読んだ後、必要な場合にどの安全でないハッシュアルゴリズムを使用するかについて良いアイデアがあると感じましたが、代わりに安全なアルゴリズムを使用する理由はわかりません。
それで、違いは何ですか?出力はハッシュされたものを表す単なる乱数ではありませんか?一部のハッシュアルゴリズムを安全にする理由は何ですか?
この興味深い質問を読んだ後、必要な場合にどの安全でないハッシュアルゴリズムを使用するかについて良いアイデアがあると感じましたが、代わりに安全なアルゴリズムを使用する理由はわかりません。
それで、違いは何ですか?出力はハッシュされたものを表す単なる乱数ではありませんか?一部のハッシュアルゴリズムを安全にする理由は何ですか?
回答:
すべての暗号化ハッシュ関数に必要な3つのプロパティがありますH
。
プレイメージ抵抗:考えるとh
、任意の値を見つけるのは難しいべきであるx
としh = H(x)
。
第2のプレイメージ抵抗:与えられてx1
、それで見つけるのx2 != x1
は難しいはずH(x1) = H(x2)
です。
衝突抵抗:それは2つの値を見つけるのは困難であるべきx1 != x2
でH(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のハッシュタグをご覧ください。
主な違いは非常に単純です。通常のハッシュは、プロセス全体の速度を落とすことなくできる範囲で、偶発的な衝突の数を最小限に抑えることを目的としています。
誰かが衝突を引き起こすために最善を尽くしている場合でも、衝突を防ぐことを目的とした安全なハッシュ。あなたは、一般的に取引したくない任意の高速化のための衝突の可能性を。実際、操作を意図的に遅くすることは、たとえ衝突を見つけにくくしなくても、それ自体にいくつかのセキュリティ上の利点があります。
後者の例:ハッシュの計算に50ミリ秒かかる場合、通常のユーザーのログインに重大な影響はありません(つまり、ほとんどのユーザーはログイン時に50ミリ秒の違いに気付きません)。同時に、攻撃者が辞書攻撃を行いたい場合、1秒あたり20ハッシュしか生成できないことは深刻なハンディキャップです。言い換えれば、何らかの理由で、安全なハッシュのためには、遅い方が良いです。
このhttp://www.codinghorror.com/blog/2012/04/speed-hashing.htmlを読んでください。これは、私が説明することができなかったすべてのことをはるかによく説明します。質問に直接対処する記事の2つの最も重要なヘッダーを次に示します。
最後の彼のTL; DRセクション:
あなたがユーザーの場合:
すべてのパスワードが12文字以上、理想的にはそれ以上であることを確認してください。パスフレーズを採用することをお勧めします。パスフレーズは、パスワード(入力しない場合)よりも覚えやすいだけでなく、純粋に長さのためにブルートフォースに対して途方もなく安全です。
開発者の場合:
セキュリティで保護する必要があるものをハッシュするには、bcryptまたはPBKDF2のみを使用してください。これらの新しいハッシュは、GPUでの実装が困難になるように特別に設計されています。他の形式のハッシュは使用しないでください。他のほとんどすべての一般的なハッシュスキームは、毎年より速く、より並列で簡単にプログラミングできる汎用GPUの配列によるブルートフォーシングに対して脆弱です。
「安全な」ハッシュとは、ハッシュの作成に使用されたメッセージを事前に知らなくても、定型的で再現可能な方法で「なりすまし」が難しいと考えられるハッシュです。その情報は一般に秘密であり、したがってハッシュの必要性があるため、これは認証での使用を目的としたハッシュ関数の優れた特性です。
メッセージM、ハッシュ関数hash()、およびハッシュ(M)によって生成されるハッシュ値H(ビットLの長さ)が与えられた場合、ハッシュは一般に「安全」と見なされます。O(2 L)時間:
さらに、「安全な」ハッシュは、2 Lコンピュータが現在のハードウェアを実行するための実行可能なステップ数ではありません。32ビット整数ハッシュは、21億の値しか持つことができません。プリイメージ攻撃(特定のハッシュHを生成するメッセージを見つける)には時間がかかりますが、多くのコンピューター、特にコード破りでチャーターされた政府機関の手にとっては実行不可能ではありません。さらに、ランダムメッセージとそのハッシュを作成して保存するアルゴリズムは、確率に従って、77,000件のメッセージだけを試行した後、新しいメッセージごとに重複ハッシュを見つけることに50%のショットを持ち、75%の確率でヒットしますわずか110,000後に複製します。64ビットハッシュでさえ、約50億の値のみを試した後でも、50%の確率で衝突します。これが、小さなハッシュに対する誕生日攻撃の力です。対照的に、十億の数字(1.5 * 10 34)。
暗号化ハッシュに対する実証された攻撃のほとんどは衝突攻撃であり、2 L時間未満で衝突メッセージを生成する能力を実証しました(ほとんどはまだ指数関数的な時間ですが、指数を半分に削減することで複雑さが大幅に軽減されます) 128ビットのように簡単に解決できる256ビットのハッシュ、64ビットのように簡単に解決できる128ビットなど)。
ハッシュサイズが小さいことに加えて、ハッシュを明らかに安全でないものにする他の要因は次のとおりです。
低作業-ハッシュテーブルで使用するため、または他の「チェックサム」タイプの目的で設計されたハッシュは、通常、計算的に安価になるように設計されています。これにより、ブルートフォース攻撃がはるかに簡単になります。
「スティッキーステート」-ハッシュ関数は、特定の追加バイトの入力が与えられたときに、これまでのすべての入力の現在のハッシュ値が変更されない入力パターンになりがちです。「スティッキー状態」があると、衝突を見つけやすくなります。「スティッキー状態」ハッシュを生成するメッセージを特定すると、ハッシュを「スティッキー状態」に保つ入力バイトを追加することにより、同じハッシュを持つ他のメッセージを生成するのは簡単です「。
拡散-メッセージの各入力バイトは、同等に複雑な方法でハッシュ値のバイトに分散される必要があります。特定のハッシュ関数は、ハッシュの特定のビットに予測可能な変更を作成します。これにより、衝突の作成が簡単になります。ハッシュを生成するメッセージが与えられた場合、予想どおりに変化するビットのみに影響する新しい値をメッセージに導入することにより、衝突を簡単に作成できます。
手元のタスクに適切なアルゴリズムを使用します。
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