.NET 框架附带 6 种不同的哈希算法:
- MD5:16 字节(哈希 500MB 的时间:1462 毫秒)
- SHA-1:20 字节(1644 毫秒)
- SHA256:32 字节(5618 毫秒)
- SHA384:48 字节(3839 毫秒)
- SHA512:64 字节(3820 毫秒)
- RIPEMD:20 字节(7066 毫秒)
这些函数中的每一个都有不同的表现; MD5 最快,RIPEMD 最慢。
MD5的优点是适合内置的Guid类型; and it is the basis of the type 3 UUID . SHA-1 hash is the basis of type 5 UUID.这使得它们非常容易用于识别。
然而,MD5 容易受到 collision attacks 的攻击, 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();
}
最佳答案
在密码学中,哈希函数提供三个独立的函数。
- 抗碰撞性:某人找到散列相同的两条消息(任何两条消息)有多难。
- Preimage Resistance:给定一个散列,找到另一条散列相同的消息有多难?也称为单向哈希函数。
- 第二原像阻力:给定一条消息,找到另一条散列相同的消息。
这些属性是相关但独立的。例如,抗碰撞性意味着第二原像抗性,但反之则不然。对于任何给定的应用程序,您将有不同的要求,需要这些属性中的一个或多个。用于在服务器上保护密码的哈希函数通常只需要原像抵抗,而消息摘要则需要所有这三个。
虽然已经证明MD5是不抗碰撞的,但这并不排除它在不需要抗碰撞的应用中的使用。事实上,MD5 通常仍用于需要较小 key 大小和速度的应用程序中。也就是说,由于其缺陷,研究人员建议在新场景中使用其他哈希函数。
SHA1 有一个缺陷,理论上可以在远少于其长度的安全哈希函数所需的 2^80 步内发现冲突。攻击不断被修改,目前可以在 ~2^63 步内完成——勉强在当前的可计算范围内(截至 2009 年 4 月)。出于这个原因,NIST 正在逐步停止使用 SHA1,并声明 SHA2 系列应该在 2010 年之后使用。
SHA2 是继 SHA1 之后创建的新哈希函数系列。目前没有针对 SHA2 函数的已知攻击。 SHA256、384 和 512 都是 SHA2 家族的一部分,只是使用不同的 key 长度。
我不能对 RIPEMD 发表太多评论,只是要注意它不像 SHA 系列那样常用,因此密码学研究人员没有仔细审查它。仅出于这个原因,我建议在它上面使用 SHA 函数。在您使用的实现中,它似乎也很慢,这使得它不太有用。
总而言之,没有最好的功能 - 这完全取决于您需要它做什么。请注意每个缺陷,您将能够最好地为您的场景选择正确的哈希函数。
⚠️警告
2022 年 8 月
请勿将 SHA-1 或 MD5 用于加密应用程序。这两种算法都已损坏(手机可在 30 秒内破解 MD5)。
关于c# - 我应该选择哪种加密哈希函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/800685/