.NET Framework поставляється з 6 різними алгоритмами хешування:
- MD5: 16 байт (час хешування 500 МБ: 1462 мс)
- SHA-1: 20 байт (1644 мс)
- SHA256: 32 байти (5618 мс)
- SHA384: 48 байт (3839 мс)
- SHA512: 64 байти (3820 мс)
- RIPEMD: 20 байт (7066 мс)
Кожна з цих функцій виконує по-різному; MD5 є найшвидшим, а RIPEMD - найповільнішим.
MD5 має ту перевагу, що він вписується у вбудований тип Guid; і це основа типу 3 UUID . Хеш SHA-1 є основою UUID типу 5. Що робить їх дійсно простими у використанні для ідентифікації.
Однак MD5 вразливий до атак зіткнення , SHA-1 також вразливий, але меншою мірою.
За яких умов я повинен використовувати алгоритм хешування?
Особливі запитання, на які мені дуже цікаво відповісти:
Не можна довіряти MD5? У звичайних ситуаціях, коли ви використовуєте алгоритм MD5 без шкідливих намірів, і жодна сторона не має жодного зловмисного наміру, ви очікуєте будь-яких зіткнень (мається на увазі два довільні байти [], що створюють один і той же хеш)
Наскільки краще RIPEMD, ніж SHA1? (якщо вона краща) її в 5 разів повільніше для обчислення, але розмір хеша такий же, як і SHA1.
Які шанси отримати нешкідливі зіткнення під час хешування імен файлів (або інших коротких рядків)? (Наприклад, 2 випадкові імена файлів з однаковим хешем MD5) (з 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();
}