[解決済み] 暗号ハッシュ関数はどれを選べばいいですか?
質問
.NETフレームワークには、6種類のハッシュアルゴリズムが同梱されています。
- MD5:16バイト(500MBのハッシュ化に要する時間:1462ms)
- SHA-1:20バイト(1644ミリ秒)
- SHA256:32バイト(5618ミリ秒)
- SHA384:48バイト(3839ミリ秒)
- SHA512:64バイト(3820ミリ秒)
- RIPEMD:20バイト(7066ミリ秒)
MD5が最も速く、RIPEMDが最も遅いというように、それぞれの関数が異なる性能を発揮します。
MD5は、組み込みのGuid型に収まるという利点があります。 であり、タイプ3のUUIDの基本である . SHA-1ハッシュは、タイプ5 UUIDのベースとなる。 そのため、識別のために実に簡単に使用することができます。
しかし、MD5は以下のような脆弱性があります。 コリジョンアタック SHA-1も脆弱ですが、その程度はそれほどでもありません。
どのような場合に、どのハッシュアルゴリズムを使うべきですか?
特に回答が欲しいのは、以下のような質問です。
-
MD5は信用できないのですか?悪意がなく、第三者が悪意を持っていない通常の状況でMD5アルゴリズムを使用する場合、衝突(任意の2つのbyte[]が同じハッシュを生成すること)が発生する可能性はありますか?
-
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();
}
解決方法は?
暗号技術において、ハッシュ関数は3つの機能を提供します。
- 耐衝突性 : 2つのメッセージ( いずれか 同じハッシュを持つ2つのメッセージ)。
- プリ画像耐性 : あるハッシュが与えられたとき、同じハッシュを持つ別のメッセージを見つけるのはどれくらい難しいか?としても知られている。 ワンウェイハッシュ関数 .
- 第二のプリ画像耐性 : あるメッセージが与えられたとき、同じハッシュを持つ別のメッセージを見つける。
これらの特性は関連しているが、独立している。例えば、耐衝突性は第2次プリ画像性を意味するが、その逆はない。どのようなアプリケーションでも、これらの特性のうち1つまたは複数を必要とする、異なる要件があるはずです。例えば、サーバー上のパスワードを保護するためのハッシュ関数では、通常、耐予像性だけが必要とされますが、メッセージダイジェストでは3つすべてが必要とされます。
MD5は耐衝突性がないことが示されていますが、だからといって耐衝突性を必要としない用途に使用することを妨げるものではありません。実際、鍵のサイズが小さく高速であることが有利なアプリケーションでは、今でもMD5がよく使われています。とはいえ、MD5には欠陥があるため、研究者は新しいシナリオでは他のハッシュ関数を使用することを推奨しています。
SHA1には、その長さの安全なハッシュ関数が必要とする2^80ステップよりも理論的にはるかに少ないステップで衝突を発見できる欠陥があります。この攻撃は継続的に修正されており、現在では2^63ステップで可能で、現在の計算可能な範囲にぎりぎり収まっています。このため、NISTはSHA1の使用を段階的に停止し、2010年以降はSHA2ファミリーを使用するよう述べています。
SHA2は、SHA1に続いて作られた新しいハッシュ関数ファミリーである。現在、SHA2関数に対する攻撃は確認されていない。SHA256、384、512はすべてSHA2ファミリーに属し、異なる鍵長を使用しているだけである。
RIPEMDについては、SHAファミリーほど一般的に使用されていないため、暗号研究者による綿密な調査が行われていないことを除けば、あまり多くのコメントはできません。そのため、私はSHA関数を使用することをお勧めします。あなたが使っている実装では、この関数はかなり遅いので、あまり役に立ちません。
結論として、最適な関数というのはありません。それぞれの欠点に注意することで、以下のような用途に適したハッシュ関数を選択することができます。 あなたの シナリオを作成します。
関連
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】2つ(またはそれ以上)のリストを1つに統合する(C# .NETで
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。
-
[解決済み] usingディレクティブはネームスペースの内側と外側のどちらを使うべきですか?
-
[解決済み] JavaでMD5ハッシュを生成するにはどうすればよいですか?
-
[解決済み] Javascriptで文字列からHashを生成する
-
[解決済み】PHPパスワードのハッシュとソルトの安全性について
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み] 関数を終了するには?
-
[解決済み】パスワードの「二重ハッシュ化」は、一度だけハッシュ化するよりも安全性が低いのでしょうか?
-
[解決済み] v5のUUIDを生成しています。名前と名前空間とは何ですか?
-
[解決済み] MD5が衝突を起こすまでのランダム要素の数は?