.NET framework có 6 thuật toán băm khác nhau:
- MD5: 16 byte (Thời gian để băm 500MB: 1462 ms)
- SHA-1: 20 byte (1644 ms)
- SHA256: 32 byte (5618 ms)
- SHA384: 48 byte (3839 ms)
- SHA512: 64 byte (3820 ms)
- RIPEMD: 20 byte (7066 ms)
Mỗi chức năng này thực hiện khác nhau; MD5 là nhanh nhất và RIPEMD là chậm nhất.
MD5 có lợi thế là nó phù hợp với loại Guid tích hợp; và nó là cơ sở của UUID loại 3 . Băm SHA-1 là cơ sở của loại 5 UUID. Điều này làm cho chúng thực sự dễ sử dụng để nhận dạng.
MD5 tuy nhiên dễ bị tấn công do va chạm , SHA-1 cũng dễ bị tổn thương nhưng ở mức độ thấp hơn.
Trong những điều kiện tôi nên sử dụng thuật toán băm nào?
Những câu hỏi đặc biệt tôi thực sự tò mò muốn xem câu trả lời là:
Là MD5 không đáng tin cậy? Trong các tình huống thông thường khi bạn sử dụng thuật toán MD5 không có mục đích độc hại và không có bên thứ ba nào có ý định độc hại, bạn sẽ mong đợi BẤT K coll va chạm nào (có nghĩa là hai byte tùy ý [] tạo ra cùng một hàm băm)
RIPEMD tốt hơn SHA1 bao nhiêu? (nếu tốt hơn) thì tính toán chậm hơn 5 lần nhưng kích thước băm giống như SHA1.
Tỷ lệ nhận được các va chạm không độc hại khi băm tên tệp (hoặc các chuỗi ngắn khác) là gì? (Ví dụ: 2 tên tệp ngẫu nhiên có cùng hàm băm MD5) (với MD5 / SHA1 / SHA2xx) Nói chung, tỷ lệ cược cho các va chạm không độc hại là gì?
Đây là điểm chuẩn tôi đã sử dụng:
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();
}