.NETフレームワークには、6つの異なるハッシュアルゴリズムが付属しています。
- MD5:16バイト(ハッシュにかかる時間500MB:1462ミリ秒)
- SHA-1:20バイト(1644ミリ秒)
- SHA256:32バイト(5618ミリ秒)
- SHA384: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();
}