どの暗号ハッシュ関数を選択すればよいですか?


137

.NETフレームワークには、6つの異なるハッシュアルゴリズムが付属しています。

  • MD5:16バイト(ハッシュにかかる時間500MB:1462ミリ秒)
  • SHA-1:20バイト(1644ミリ秒)
  • SHA256:32バイト(5618ミリ秒)
  • SHA3​​84:48バイト(3839ミリ秒)
  • SHA512:64バイト(3820ミリ秒)
  • RIPEMD:20バイト(7066 ms)

これらの機能はそれぞれ異なる方法で実行されます。MD5が最も速く、RIPEMDが最も遅い。

MD5には、組み込みのGuidタイプに適合するという利点があります。そして、それはタイプ3 UUIDの基礎ですSHA-1ハッシュはタイプ5 UUIDの基礎です。これにより、識別に非常に使いやすくなります。

ただし、MD5は衝突攻撃に対して脆弱です。SHA-1も脆弱ですが、程度は低くなります。

どのハッシュアルゴリズムをどの条件で使用すればよいですか?

私が答えを見て本当に興味がある特定の質問は次のとおりです。

  • MD5は信頼されないのですか?悪意のない意図でMD5アルゴリズムを使用し、第三者が悪意のある意図を持たない通常の状況では、すべての衝突が予想されます(2つの任意のバイト[]が同じハッシュを生成することを意味します)

  • RIPEMDはSHA1よりどのくらい優れていますか?(より良い場合)計算が5倍遅くなりますが、ハッシュサイズはSHA1と同じです。

  • ファイル名(または他の短い文字列)をハッシュするときに、悪意のない衝突が発生する確率はどれくらいですか?(例:同じMD5ハッシュを持つ2つのランダムなファイル名)(MD5 / SHA1 / SHA2xxを使用)一般に、悪意のない衝突の確率はどれくらいですか?

これは私が使用したベンチマークです:

    static void TimeAction(string description, int iterations, Action func) {
        var watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < iterations; i++) {
            func();
        }
        watch.Stop();
        Console.Write(description);
        Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
    }

    static byte[] GetRandomBytes(int count) {
        var bytes = new byte[count];
        (new Random()).NextBytes(bytes);
        return bytes;
    }


    static void Main(string[] args) {

        var md5 = new MD5CryptoServiceProvider();
        var sha1 = new SHA1CryptoServiceProvider();
        var sha256 = new SHA256CryptoServiceProvider();
        var sha384 = new SHA384CryptoServiceProvider();
        var sha512 = new SHA512CryptoServiceProvider();
        var ripemd160 = new RIPEMD160Managed();

        var source = GetRandomBytes(1000 * 1024);

        var algorithms = new Dictionary<string,HashAlgorithm>();
        algorithms["md5"] = md5;
        algorithms["sha1"] = sha1;
        algorithms["sha256"] = sha256;
        algorithms["sha384"] = sha384;
        algorithms["sha512"] = sha512;
        algorithms["ripemd160"] = ripemd160;

        foreach (var pair in algorithms) {
            Console.WriteLine("Hash Length for {0} is {1}", 
                pair.Key, 
                pair.Value.ComputeHash(source).Length);
        }

        foreach (var pair in algorithms) {
            TimeAction(pair.Key + " calculation", 500, () =>
            {
                pair.Value.ComputeHash(source);
            });
        }

        Console.ReadKey();
    }

15
md5がGUID(16バイト)形式に適合しているということは、根本的な誤解を示唆しています。ハッシュは一意であることが保証されていませんが、まれであり(暗号化の意味で使用すると偽造が困難です)、ハッシュであることに由来しますが、GUIDは一意ですが、GUIDのコンテンツとは無関係です。それが識別するもの。それらは非常に異なる目的で使用されます。
Barry Wark

1
その無関係な、それは単なる便利な実装固有の事実を修正します。無限を16バイトに収めることができないことを理解しています。すべてのハッシュアルゴリズムとの衝突が発生する可能性があります
Sam Saffron、

5
また、Guidは実際にはユニークであり、理論的には、Guidを生成し続けると、最終的には重複することになります。
サムサフラン

3
あなたは本当にべきではない、それがフィットしていても、GUIDにハッシュを詰め込みます。最も単純な例:同じファイルの2つのコピーは、GUIDは異なるがハッシュは同じである必要があります。人の名前の最初の8文字も16バイトにかなりうまく収まります。
dbkk

2
@ user2332868 SHA-1の中断は、偶発的な衝突の確率には影響しません。悪意のある意図があなたの使用にとって脅威である場合、私は盲目的にハッシュ関数を選ぶことは間違っていると思います、そしてあなたはあなたの特定のケースのためにリスク/コスト分析を行う時間を費やす必要があります。
Andrey Tarantsov

回答:


138

暗号化では、ハッシュ関数は3つの別個の関数を提供します。

  1. 衝突抵抗:2つのメッセージ(どれでも同じハッシュの2 2つのメッセージ)。
  2. Preimage Resistance:ハッシュが与えられた場合、同じハッシュを持つ別のメッセージを見つけるのはどれほど難しいですか?一方向ハッシュ関数とも呼ばれます
  3. 第二のプリイメージ抵抗:メッセージ、同じハッシュを別のメッセージを見つけることを考えます。

これらのプロパティは関連していますが、独立しています。たとえば、衝突耐性は2番目のプリイメージ耐性を意味しますが、その逆は意味しません。特定のアプリケーションでは、さまざまな要件があり、これらのプロパティの1つ以上が必要です。サーバー上のパスワードを保護するためのハッシュ関数は通常、プリイメージ耐性のみを必要としますが、メッセージダイジェストには3つすべてが必要です。

MD5は耐衝突性ではないことが示されていますが、耐衝突性を必要としないアプリケーションでの使用を妨げるものではありません。実際、MD5は、キーのサイズと速度が小さい方が有利なアプリケーションでよく使用されます。とはいえ、その欠陥のため、研究者たちは新しいシナリオで他のハッシュ関数を使用することを推奨しています。

SHA1には、理論的には、その長さの安全なハッシュ関数が必要とする2 ^ 80ステップよりもはるかに少ない回数で衝突を発見できる欠陥があります。攻撃は絶えず修正されており、現在は約2 ^ 63ステップで実行できます-計算能力の現在の領域内でわずかです。このため、NISTはSHA1の使用を段階的に廃止し、SHA2ファミリーは2010年以降に使用する必要があると述べています。

SHA2は、SHA1に続いて作成されたハッシュ関数の新しいファミリです。現在、SHA2機能に対する既知の攻撃はありません。SHA256、384、512はすべてSHA2ファミリーの一部であり、異なるキーの長さを使用しているだけです。

RIPEMDについてはあまりコメントできません。ただし、SHAファミリーほど一般的に使用されていないため、暗号研究者による詳細な調査は行われていません。その理由だけで、私はSHA機能を使用することをお勧めします。あなたが使用している実装でも同様に非常に遅いように見え、それがあまり役に立たなくなります。

結論として、最良の機能は1つではありません-それはすべて、何のために必要かによって異なります。それぞれの欠点に注意してください。そうすればシナリオに適したハッシュ関数を選択することができます。


1
このレベルの詳細にご理解いただき、誠にありがとうございます。これは非常に役立ちます。
joelc

1
一部のアプリケーションでは、非暗号グレードのハッシュ関数でも適切な場合があります。特に、パスワード、チャレンジ/レスポンス認証、アクセストークン、または一連の文字列/ファイルにインデックスを付けるためのOPについては言及していません。一方、パフォーマンスはOPの懸念事項です...
Seva Alekseyev

111

すべてのハッシュ関数は「壊れている」

鳩の巣原理は(あなたが鳩を切っていない限り)あなたは2つの穴の中に2つ以上のハトに適合しないことができますように、ハードとしてその試みを言います。同様に、2 ^ 128スロットに2 ^ 128 + 1の数値を収めることはできません。すべてのハッシュ関数の結果は有限サイズのハッシュになります。つまり、「有限サイズ」+1シーケンスを検索すると、常に衝突を見つけることができます。それを行うのは現実的ではありません。MD5とSkeinには対応していません。

MD5 / SHA1 / Sha2xxが衝突する可能性はありません

すべてのハッシュ関数には衝突がありますが、これは事実です。偶然にこれらの衝突に遭遇することは、銀河間宝くじ当選することと同じです。つまり、銀河系間の宝くじに当選する人誰もいません。宝くじの仕組みだけではありません。偶発的なMD5 / SHA1 / SHA2XXXハッシュに遭遇することはありません。すべての辞書、すべての言語のすべての単語は、異なる値にハッシュされます。惑星全体のすべてのマシンのすべてのパス名には、異なるMD5 / SHA1 / SHA2XXXハッシュがあります。どうやってそれを知るのか、あなたは尋ねるかもしれません。さて、前にも言ったように、銀河系の宝くじに当選する人はいません。

しかし... MD5は壊れています

時々、その壊れているという事実は重要ではありません

現状では、既知のプリイメージ攻撃や2番目のプリイメージ攻撃はありません、MD5。

では、MD5の何がそれほど壊れているのでしょうか。サードパーティが2つのメッセージを生成する可能性があります。1つはEVIL、もう1つはGOODで、どちらも同じ値にハッシュされます。(衝突攻撃

それにもかかわらず、現在のRSAの推奨事項は、プレイメージ耐性が必要な場合はMD5を使用しないことです。セキュリティアルゴリズムに関しては、注意を怠る傾向があります。

では、.NETではどのハッシュ関数を使用すればよいですか?

  • 速度/サイズが必要で、誕生日攻撃やプリイメージ攻撃を気にしない場合は、MD5を使用してください。

私の後にこれを繰り返します。MD5衝突の可能性はありません。悪意のある衝突は慎重に設計できます。MD5にはこれまでに既知のプリイメージ攻撃はありませんが、セキュリティの専門家によると、プリイメージ攻撃を防御する必要がある場合はMD5を使用しないでください。SAMEはSHA1に使用されます。

すべてのアルゴリズムがプリイメージ攻撃や衝突攻撃を防御する必要があるわけではないことに注意してください。HD上の重複ファイルの最初のパス検索のささいなケースを考えてみましょう。

  • 暗号的に安全なハッシュ関数が必要な場合は、SHA2XXベースの関数を使用します。

SHA512の衝突を発見した人はいません。これまで。彼らは本当に一生懸命頑張ってきました。さらに言えば、SHA256や384の衝突を発見した人はいません。。

  • 相互運用性のシナリオでない限り、SHA1またはRIPEMDを使用しないでください。

RIPMEDは、SHAXおよびMD5が受けたのと同じ量の精査を受けていません。SHA1とRIPEMDはどちらも誕生日攻撃に対して脆弱です。どちらも.NETのMD5よりも低速で、扱いにくい20バイトサイズになります。これらの関数を使用しても意味がないので、忘れてください。

SHA1衝突攻撃は2 ^ 52に減少し、SHA1衝突が実際に出回るまで、それほど長くは続きません。

さまざまなハッシュ関数の最新情報については、ハッシュ関数zooをご覧ください。

もっと待ってください

高速なハッシュ関数を持つことは呪いになることがあります。たとえば、ハッシュ関数の非常に一般的な使用法はパスワードの保存です。基本的に、既知のランダム文字列と組み合わせたパスワードのハッシュを計算し(レインボー攻撃を防ぐため)、そのハッシュをデータベースに格納します。

問題は、攻撃者がデータベースのダンプを取得した場合、ブルートフォースを使用して非常に効果的にパスワードを推測できることです。彼が試みるすべての組み合わせはミリ秒のほんの数分しかかかりません、そして彼は毎秒数十万のパスワードを試すことができます。

この問題を回避するには、bcryptアルゴリズムを使用できます。これは低速になるように設計されているため、bcryptを使用してシステムを攻撃する場合、攻撃者は大幅に減速します。最近scryptはいくつかの見出しをつけており、bcryptよりも効果的であると考える人もいますが、.Net実装については知りません。


MD5とSHA-1の両方が弱められていますが、MD5はSHA-1よりもはるかに弱く、わずかに速くなっています。実際のMD5衝突が発見され、実際のエクスプロイト(CA証明書の偽造)に使用されていますが、私の知る限り、実際のSHA-1衝突は発見されていません(ただし、操作の数はブルートフォースにより大幅に削減されています)。また、MD5の強度がどれほど弱いかを考えると、2番目のプリイメージ攻撃がSHA-1よりもMD5の方が早く現れたとしても、私は驚かないでしょう。したがって、速度と衝突抵抗を必要としない場合はSHA-1を使用し、それ以外の場合はSHA-2ファミリーの1つを使用する必要があると思います。
ブライアンキャンベル

1
@Brianは、今後数年以内に人々がSHA1に対して衝突攻撃を実行できるようになることはかなり明確です。これにより、SHA1はMD5と同じくらい有効になります。CA証明書は衝突攻撃であり、同様に数年後に人々はSHA1 CA証明書に対して同じ攻撃を実行します。攻撃は、悪意のある当事者がEVILおよびGOOD証明書を作成することに依存します。MD5での既知の原始攻撃はなく、衝突攻撃があるという事実は、プリイメージ攻撃を多かれ少なかれ可能にしません。
サムサフラン

パスワードにどのハッシュを使用するかは、ハッシュされるものよりもはるかに少ないです。ソルトがわかっている場合、データベースはすぐに辞書攻撃に対して脆弱になります。ソルトが手続き型であり、ファイルシステムが危険にさらされている場合、(再び)脆弱です。あなたの塩が省略されている場合は、再び侵害されます。問題のセキュリティは、何がハッシュされているかです。証明書。プログラマー(IE、作成、理解など)として扱っていないため、ここでは触れません。
Robert K、

壊れたという用語には、ハッシュのコンテキストで特定の意味があり、この回答が強調する意味ではありません。この答えはすべて混乱を引き起こします。
ジョエルマクベス

1
これは実用性に焦点を当てているため、優れた答えです。ハッシュは、セキュリティ以外の目的で使用されます(機密ではないデータのキャッシュルックアップキーの生成、シリアル化されたオブジェクトが変更されたかどうかの判断など)。標的型攻撃の可能性は事実上ゼロ(決して決して言わない)であり、攻撃が成功したとしても、重大な影響はありません。(理論的なものではなく)実際的な影響に焦点を当てた優れた仕事。
DVK 2016

35

更新:

時代は変わりました、SHA3の勝者がいます。私が使用することをお勧めしますkeccakを(別名SHA3 SHA3コンテストの優勝者)。

元の回答:

最も弱いものから最も強いものの順に、私は言うでしょう:

  1. RIPEMD BROKEN、このPDFにあるように、使用ないでください
  2. MD-5 破損、使用しないでください。ラップトップを使用すると2分で壊れる可能性があります
  3. SHA-1 BROKEN、使用するべきではない、原則的に壊れている、攻撃は週ごとに良くなっている
  4. SHA-2 WEAK、おそらく今後数年で壊れるでしょう。いくつかの弱点が見つかりました。一般に、キーのサイズが大きいほど、ハッシュ関数の解読が難しくなります。キーサイズ=強度は常に正しいとは限りませんが、ほとんどの場合は正しいです。したがって、SHA-256はおそらくSHA-512よりも弱いです。
  5. Skein NO KNOWN WEAKNESSES は、SHA-3の候補です。これはかなり新しいため、テストされていません。多くの言語で実装されています。
  6. MD6 NO KNOWN WEAKNESSESは、SHA-3のもう1つの候補です。おそらくSkienより強力ですが、シングルコアマシンでは遅くなります。シェーエンのように、それはテストされていません。一部のセキュリティ志向の開発者は、ミッションクリティカルな役割でそれを使用しています

個人的にはMD6を使用します。速度が本当に重要な場合は、SkeinまたはSHA-256を検討します。


5
私はSkeinとMD6をそれほど高くリストに入れません。SHA-3コンテストが2012年末まで終了しないのには理由があります。ハッシュ関数が実際に安全である可能性が高く、これらの関数のどちらもないことを確信するには長い時間と多くの目がかかりますそのために十分な長さでした。
エリックバーネット

あなたの意見には同意しますが、コミュニティは奇妙な立場にあると思います。使用中のすべてのハッシュ関数は壊れる危険性が非常に高く(SHA2 256-512ではないかもしれません)、それでも2012年まで代替品を選択する必要があります。毒を選択する:弱い/壊れている、またはテストされていない(ほとんどのNIST候補者は6か月以上公開されていません)?厳しい選択。
イーサンハイルマン、

5
RIPEMDは壊れていますが、RIPEMD-128 / 160/256は異なり、壊れていません。
Bwooce、2011

Skein for .NETのパフォーマンスの高い実装については知りません。SkeinFishとnskeinに出会いましたが、どちらも非常に低速でした。
Cocowalla

1
少なくとも実際に標準にしたいのであれば、実際の標準が出るまでSHA-3を使用するのを待ちます。アルゴリズム自体のオプションが多すぎます。
–PaŭloEbermann 2013

3

MD5を防御するために、任意のMD5ハッシュを使用してファイルを作成する方法は知られていません。元の作成者は、衝突が発生するように事前に計画する必要があります。したがって、受信者が送信者を信頼する場合、MD5は問題ありません。署名者が悪意のある場合、MD5は破られますが、中間者攻撃に対して脆弱であるとは知られていません。


1
私は決してこの分野の専門家ではありませんが、現在、ブルートフォースで任意のMD5ハッシュを計算することは、ほぼ可能ではありませんか?
mafu

@mafu:ここでは遅い応答ですが、ブルートフォースを介してハッシュを計算することは可能です。本当に時間がかかるかもしれません。
Warty

@ItzWarty必要な時間について具体的に言及していました-MD5はかなり短いため、合理的なコンピューティングソース(E3、または安価なコンピューターグリッド、グラフィックカードがいくつかある数台のマシンなど)を単純に投入できる可能性があると考えましたこれらの線に沿って)、たとえば、数日以内に任意のMD5ハッシュを計算できるようになります。
mafu 2013

@mafuプリイメージ攻撃では、128ビットハッシュに対して2 ^ 127回のハッシュ呼び出しが必要です。これは実現可能ではありません。2 ^ 80の呼び出しは実行可能ですが、すでに非常に高価です。
CodesInChaos 2014年

2

どちらを使用するかは、実際に何に使用するかによって異なります。転送中にファイルが破損しないようにしたいだけで、セキュリティについてそれほど心配していない場合は、高速で小規模なものを使用してください。数十億ドル規模の連邦救済協定のデジタル署名が必要であり、それが偽造されていないことを確認する必要がある場合は、なりすましを遅らせて速度を落とすようにしてください。


1
問題の解決策について話し合うときに、MD5を使用してすばやく識別(文字列をハッシュ化)していると何度も言っています。何かが根本的に壊れており、一部の弱いハッシュで回避する必要がある場合...たとえば、通常のデータが衝突を引き起こす実際の作業のケース
Sam Saffron

MD5が15年間何百万人もの人々に問題なく機能したことを考えると、ハッシュのセキュリティが重要ではないとしても、それは問題ないと思います。
mqp 2009

2
@sambo MD5は、システムの実際のセキュリティ/完全性が衝突の防止に依存している場合を除いて、ほとんどすべての場合に問題なく機能します。
レックスM

2

(md5がバラバラになる前に)多くの暗号化の圧倒的な破損にもかかわらず、まだmd5を広範囲に使用していることを伝えたいと思います。

衝突から保護する必要がなく(hmacでもmd5を使用しても安全です)、速度が必要な場合(低速なハッシュが必要な場合もあります)、md5を自信を持って使用できます。


@Mike私はあなたと一緒にいます、それは私がこの質問で掘り下げていたもののようなもので、根本的に壊れているので決して使用されるべきではない弱いハッシュ関数についての何かです。
サムサフラン

これに加えて、データまたはデータの必要なセキュリティの寿命がクラック期間(最近数分iirc)より短い場合、MD5は完全に問題ありません。状況的には有用ですが、それでも有用なのがポイントです。
アナカタ2009年

@annakata-複数のメッセージでキーを再利用しないようにして、そのような状況で使用できるようにする必要があることにも注意してください。
Steve Westbrook 2013年

2

BLAKE2を見てみるといいです algorythmを。

説明されているように、MD5より高速で、少なくともSHA-3と同じくらい安全です。また、WinRarを含むいくつかのソフトウェアアプリケーションによって実装されます


SHA-256を非常に高速にするハードウェアサポートが多くの実装にあることを除いて、それはより高速かもしれません。
zaph 2016

同意する。2019年現在、Blake2bはこれまでにリリースされた最高の汎用ハッシュです。他のすべての代替手段よりも大幅に高速で、安全性も低くなく(少なくとも意味のある方法ではない)、RAMは336バイト(blake2sの場合は168)だけで実行でき、リトルエンディアンCPU向けに最適化されています。今日のシステムの支配的なエンディアン。
hanshenrik

0

私はこの種のものの専門家ではありませんが、セキュリティコミュニティに追いついており、多くの人々がmd5ハッシュが壊れていると考えています。どちらを使用するかは、データの機密性と特定のアプリケーションに依存すると思います。キーが適切で強力なものである限り、少し安全性の低いハッシュで回避できる可能性があります。


1
ハッシュ関数は通常、キーを使用しません
Ethan Heilman、

0

これがあなたへの私の提案です:

  1. 攻撃が予想される場合は、MD5を忘れてください。オンラインにはレインボーテーブルがたくさんあり、RIAAのような企業は、同等のハッシュを持つシーケンスを生成できることが知られています。
  2. できれば塩を使いましょう。メッセージにメッセージの長さを含めると、有用なハッシュ衝突を行うことが非常に困難になる可能性があります。
  3. 一般的な経験則として、ビット数が多いほど、衝突が少なくなり(鳩の巣の原理による)、速度が遅くなり、おそらくより安全になります(脆弱性を見つけることができる数学の天才でない限り)。

デスクトップIntel P4コンピューターとのmd5衝突を31秒で作成するアルゴリズムの詳細については、ここを参照してください。

http://eprint.iacr.org/2006/105


このコメントは非常に古く、かなり埋もれているように見えますが、このビット-RIAA は同等のハッシュを使用してシーケンスを生成できることが知られています -私から飛び出しました。特に、8年前のMD5​​のブルートフォーシングは、2017年よりも簡単なことではなかったので、かなり正当な理由があったはずです。
i336_ 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.