C# 我应该选择哪种加密哈希函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/800685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:42:18  来源:igfitidea点击:

Which cryptographic hash function should I choose?

c#.nethashcryptographycryptographic-hash-function

提问by Sam Saffron

The .NET framework ships with 6 different hashing algorithms:

.NET 框架附带 6 种不同的散列算法:

  • MD5: 16 bytes (Time to hash 500MB: 1462 ms)
  • SHA-1: 20 bytes (1644 ms)
  • SHA256: 32 bytes (5618 ms)
  • SHA384: 48 bytes (3839 ms)
  • SHA512: 64 bytes (3820 ms)
  • RIPEMD: 20 bytes (7066 ms)
  • MD5:16 字节(散列时间 500MB:1462 毫秒)
  • SHA-1:20 字节(1644 毫秒)
  • SHA256:32 字节(5618 毫秒)
  • SHA3​​84:48 字节(3839 毫秒)
  • SHA512:64 字节(3820 毫秒)
  • RIPEMD:20 字节(7066 毫秒)

Each of these functions performs differently; MD5 being the fastest and RIPEMD being the slowest.

这些功能中的每一个都有不同的表现;MD5 是最快的,而 RIPEMD 是最慢的。

MD5 has the advantage that it fits in the built-in Guid type; and it is the basis of the type 3 UUID. SHA-1 hash is the basis of type 5 UUID.Which makes them really easy to use for identification.

MD5 的优点是适合内置的 Guid 类型;它是类型 3 UUID 的基础SHA-1 哈希是类型 5 UUID 的基础。这使它们非常易于用于识别。

MD5 however is vulnerable to collision attacks, SHA-1 is also vulnerable but to a lesser degree.

然而,MD5 容易受到碰撞攻击,SHA-1 也容易受到攻击,但程度较轻。

Under what conditions should I use which hashing algorithm?

在什么情况下我应该使用哪种散列算法?

Particular questions I'm really curious to see answered are:

我真的很想知道答案的具体问题是:

  • Is MD5 not to be trusted? Under normal situations when you use the MD5 algorithm with no malicious intent and no third party has any malicious intent would you expect ANY collisions (meaning two arbitrary byte[] producing the same hash)

  • How much better is RIPEMD than SHA1? (if its any better) its 5 times slower to compute but the hash size is the same as SHA1.

  • What are the odds of getting non-malicious collisions when hashing file-names (or other short strings)? (Eg. 2 random file-names with same MD5 hash) (with MD5 / SHA1 / SHA2xx) In general what are the odds for non-malicious collisions?

  • MD5 不值得信任吗?在正常情况下,当您无恶意地使用 MD5 算法并且没有第三方有任何恶意时,您会期望任何冲突(意味着两个任意字节 [] 产生相同的哈希)

  • RIPEMD 比 SHA1 好多少?(如果它更好)它的计算速度慢了 5 倍,但哈希大小与 SHA1 相同。

  • 在对文件名(或其他短字符串)进行哈希处理时,发生非恶意冲突的几率有多大?(例如,具有相同 MD5 哈希值的 2 个随机文件名)(具有 MD5 / SHA1 / SHA2xx) 一般来说,非恶意冲突的几率是多少?

This is the benchmark I used:

这是我使用的基准:

    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();
    }

采纳答案by Eric Burnett

In cryptography, hash functions provide three separate functions.

在密码学中,散列函数提供三个独立的函数。

  1. Collision resistance: How hard is it for someone to find two messages (anytwo messages) that hash the same.
  2. Preimage Resistance: Given a hash, how hard is it to find another message that hashes the same? Also known as a one way hash function.
  3. Second preimage resistance: Given a message, find another message that hashes the same.
  1. 抗冲突性:某人找到散列相同的两条消息(任意两条消息)有多难。
  2. Preimage Resistance:给定一个散列,找到另一个散列相同的消息有多难?也称为单向哈希函数
  3. 第二个原像阻力:给定一条消息,找到另一条散列相同的消息。

These properties are related but independent. For example, collision resistance implies second preimage resistance, but not the other way around. For any given application, you will have different requirements, needing one or more of these properties. A hash function for securing passwords on a server will usually only require preimage resistance, while message digests require all three.

这些属性是相关但独立的。例如,抗碰撞性意味着第二个原像抗性,而不是相反。对于任何给定的应用程序,您将有不同的要求,需要这些属性中的一个或多个。用于保护服务器密码的散列函数通常只需要抗原像,而消息摘要则需要所有三个。

It has been shown that MD5 is not collision resistant, however, that does not preclude its use in applications that do not require collision resistance. Indeed, MD5 is often still used in applications where the smaller key size and speed are beneficial. That said, due to its flaws, researchers recommend the use of other hash functions in new scenarios.

已经表明 MD5 不抗碰撞,但是,这并不排除它在不需要抗碰撞的应用中的使用。事实上,MD5 通常仍然用于较小的密钥大小和速度有益的应用程序中。也就是说,由于其缺陷,研究人员建议在新场景中使用其他哈希函数。

SHA1 has a flaw that allows collisions to be found in theoretically far less than the 2^80 steps a secure hash function of its length would require. The attack is continually being revised and currently can be done in ~2^63 steps - just barely within the current realm of computability. For this reason NIST is phasing out the use of SHA1, stating that the SHA2 family should be used after 2010.

SHA1 有一个缺陷,它允许在理论上远远少于其长度的安全散列函数所需的 2^80 步内发现冲突。攻击不断被修改,目前可以在大约 2^63 个步骤中完成 - 仅在当前的可计算范围内。出于这个原因,NIST 正在逐步淘汰 SHA1 的使用,并指出 SHA2 系列应在 2010 年之后使用。

SHA2 is a new family of hash functions created following SHA1. Currently there are no known attacks against SHA2 functions. SHA256, 384 and 512 are all part of the SHA2 family, just using different key lengths.

SHA2 是在 SHA1 之后创建的一个新的哈希函数系列。目前没有针对 SHA2 函数的已知攻击。SHA256、384 和 512 都是 SHA2 系列的一部分,只是使用了不同的密钥长度。

RIPEMD I can't comment too much on, except to note that it isn't as commonly used as the SHA families, and so has not been scrutinized as closely by cryptographic researchers. For that reason alone I would recommend the use of SHA functions over it. In the implementation you are using it seems quite slow as well, which makes it less useful.

RIPEMD 我不能过多评论,只是要注意它不像 SHA 系列那样常用,因此没有受到密码研究人员的仔细。仅出于这个原因,我建议在它上面使用 SHA 函数。在您使用的实现中,它似乎也很慢,这使得它不太有用。

In conclusion, there is no one best function - it all depends on what you need it for. Be mindful of the flaws with each and you will be best able to choose the right hash function for yourscenario.

总之,没有最好的功能 - 这完全取决于您需要它的用途。请注意每个的缺陷,您将能够最好地为您的场景选择正确的哈希函数。

回答by tvanfosson

Which one you use really depends on what you are using it for. If you just want to make sure that files don't get corrupted in transit and aren't that concerned about security, go for fast and small. If you need digital signatures for multi-billion dollar federal bailout agreements and need to make sure they aren't forged, go for hard to spoof and slow.

您使用哪一种实际上取决于您使用它的目的。如果您只是想确保文件在传输过程中不会被损坏并且不那么关心安全性,请选择快速和小型。如果您需要数十亿美元的联邦救助协议的数字签名,并且需要确保它们不是伪造的,请努力欺骗和减缓。

回答by Mike Boers

I would like to chime in (before md5 gets torn apart) that I do still use md5 extensively despite its overwhelming brokenness for a lot of crypto.

我想补充一下(在 md5 被撕裂之前)我仍然广泛使用 md5,尽管它对许多加密货币具有压倒性的破坏性。

As long as you don't care to protect against collisions (you are still safe to use md5 in an hmac as well) and you do want the speed (sometimes you want a slower hash) then you can still use md5 confidently.

只要你不关心防止冲突(你仍然可以安全地在 hmac 中使用 md5)并且你确实想要速度(有时你想要更慢的哈希)那么你仍然可以自信地使用 md5。

回答by blueintegral

I am not an expert at this sort of thing, but I keep up with the security community and a lot of people there consider the md5 hash broken. I would say that which one to use depends on how sensitive the data is and the specific application. You might be able to get away with a slightly less secure hash as long as the key is good and strong.

我不是这类事情的专家,但我跟上安全社区的步伐,那里的很多人都认为 md5 哈希被破坏了。我会说使用哪个取决于数据的敏感程度和特定应用程序。只要密钥是好的和强大的,您就可以使用稍微不那么安全的散列。

回答by Unknown

Here are my suggestions for you:

以下是我给你的建议:

  1. You should probably forget MD5 if you anticipate attacks. There are many rainbow tablesfor them online, and corporations like the RIAA have been known to be able to produce sequences with equivalent hashes.
  2. Use a saltif you can. Including the message length in the message can make it very difficult to make a useful hash collision.
  3. As a general rule of thumb, more bits means less collisions (by pigeonhole principle) and slower, and maybe more secure (unless you are a math genius who can find vulnerabilities).
  1. 如果您预计会受到攻击,您可能应该忘记 MD5。网上有许多彩虹表可供他们使用,众所周知,像 RIAA 这样的公司能够生成具有等效哈希值的序列。
  2. 如果可以,请使用。在消息中包含消息长度可能会导致很难进行有用的散列冲突。
  3. 作为一般经验法则,更多的位意味着更少的冲突(根据鸽巢原理),更慢,也许更安全(除非你是一个能找到漏洞的数学天才)。

See here for a paper detailing an algorithm to create md5 collisions in 31 seconds with a desktop Intel P4 computer.

请参阅此处的论文,其中详细介绍了在 31 秒内使用台式英特尔 P4 计算机创建 md5 冲突的算法。

http://eprint.iacr.org/2006/105

http://eprint.iacr.org/2006/105

回答by rlbond

In MD5's defense, there is no known way to produce a file with an arbitrary MD5 hash. The original author must plan in advance to have a working collision. Thus if the receiver trusts the sender, MD5 is fine. MD5 is broken if the signer is malicious, but it is not known to be vulnerable to man-in-the-middle attacks.

在 MD5 的防御中,没有已知的方法可以生成具有任意 MD5 哈希值的文件。原作者必须提前计划好有工作冲突。因此,如果接收方信任发送方,则 MD5 没问题。如果签名者是恶意的,则 MD5 被破坏,但不知道它容易受到中间人攻击。

回答by Ethan Heilman

Update:

更新:

Times have changed, we have a SHA3 winner. I would recommend using keccak(aka SHA3) winner of the SHA3 contest.

时代变了,我们有了 SHA3 冠军。我建议使用keccak(又名SHA3) SHA3 比赛的获胜者。

Original Answer:

原答案:

In order of weakest to strongest I would say:

按照从弱到强的顺序,我会说:

  1. RIPEMD BROKEN, Should never be used as can be seen in this pdf
  2. MD-5 BROKEN, Should never be used, can be broken in 2 minutes with a laptop
  3. SHA-1 BROKEN, Should never be used, is broken in principal, attacks are getting better by the week
  4. SHA-2 WEAK, Will probably be broken in the next few years. A few weaknesses have been found.Note that generally the higher key size, the harder the hash function is to break. While key size = strength is not always true, it is mostly true. So SHA-256 is probably weaker than SHA-512.
  5. Skein NO KNOWN WEAKNESSES, is a candidate for SHA-3. It is fairly new and thus untested. It has been implemented in a bunch of languages.
  6. MD6 NO KNOWN WEAKNESSES, is another a candidate for SHA-3. Probably stronger than Skien, but slower on single core machines. Like Skien it is untested. Some security minded developers are using it, in mission critical roles.
  1. RIPEMD BROKEN,如本 pdf 所示,绝不应使用
  2. MD-5 BROKEN, 绝对不能使用,用笔记本电脑2分钟就可以坏掉
  3. SHA-1 BROKEN,永远不应该使用,原则上已损坏,每周攻击越来越好
  4. SHA-2 弱,可能会在未来几年内被打破。发现了一些弱点。请注意,通常密钥大小越大,哈希函数就越难破解。虽然密钥大小 = 强度并不总是正确的,但大多数情况下是正确的。所以 SHA-256 可能比 SHA-512 弱。
  5. Skein NO KNOWN WEAKNESSES,是 SHA-3 的候选者。它是相当新的,因此未经测试。它已用多种语言实现。
  6. MD6 NO KNOWN WEAKNESSES,是 SHA-3 的另一个候选者。可能比 Skien 强,但在单核机器上速度较慢。像斯基恩一样,它是未经测试的。一些具有安全意识的开发人员正在以关键任务角色使用它。

Personally I'd use MD6, because one can never been too paranoid. If speed is a real concern I'd look at Skein, or SHA-256.

我个人会使用 MD6,因为人们永远不会太偏执。如果速度是一个真正的问题,我会看看 Skein 或 SHA-256。

回答by Sam Saffron

All hash functions are "broken"

所有散列函数都被“破坏”

The pigeonhole principlesays that try as hard as you will you can not fit more than 2 pigeons in 2 holes (unless you cut the pigeons up). Similarly you can not fit 2^128 + 1 numbers in 2^128 slots. All hash functions result in a hash of finite size, this means that you can always find a collision if you search through "finite size" + 1 sequences. It's just not feasible to do so. Not for MD5 and not for Skein.

鸽巢原理说,尝试努力,你将无法在2个孔适合超过2只鸽子(除非你砍鸽子了)。同样,您不能在 2^128 个插槽中容纳 2^128 + 1 个数字。所有散列函数都会产生有限大小的散列,这意味着如果您搜索“有限大小”+ 1 个序列,您总是可以找到冲突。这样做是不可行的。不适用于 MD5 也不适用于Skein

MD5/SHA1/Sha2xx have no chance collisions

MD5/SHA1/Sha2xx 没有机会碰撞

All the hash functions have collisions, its a fact of life. Coming across these collisions by accident is the equivalent of winning the intergalactic lottery. That is to say, no one wins the intergalactic lottery, its just not the way the lottery works. You will not come across an accidental MD5/SHA1/SHA2XXX hash, EVER. Every word in every dictionary, in every language, hashes to a different value. Every path name, on every machine in the entire planet has a different MD5/SHA1/SHA2XXX hash. How do I know that, you may ask. Well, as I said before, no one wins the intergalactic lottery, ever.

所有的哈希函数都有冲突,这是生活中的事实。偶然遇到这些碰撞就相当于中了星际彩票。也就是说,没有人中奖星际彩票,只是彩票的运作方式不同而已。您永远不会遇到意外的 MD5/SHA1/SHA2XXX 哈希。每本词典、每一种语言中的每一个词,都会散列到不同的值。地球上每台机器上的每个路径名都有不同的 MD5/SHA1/SHA2XXX 哈希值。我怎么知道,你可能会问。好吧,正如我之前所说,从来没有人中过星际彩票。

But ... MD5 is broken

但是...... MD5坏了

Sometimes the fact that its broken does not matter.

有时,它破碎的事实并不重要

As it stands there are no known pre-image or second pre-image attackson MD5.

就目前而言,没有已知的对 MD5 的原像或第二原像攻击

So what is so broken about MD5, you may ask? It is possible for a third party to generate 2 messages, one of which is EVIL and another of which is GOOD that both hash to the same value. (Collision attack)

那么,您可能会问,MD5 有什么问题?第三方可能会生成 2 条消息,其中一条是 EVIL,另一条是 GOOD,它们都散列到相同的值。(碰撞攻击

Nonetheless, the current RSA recommendation is not to use MD5 if you need pre-image resistance. People tend to err on the side of caution when it comes to security algorithms.

尽管如此,如果您需要原像阻力,当前的 RSA 建议是不要使用 MD5。当涉及到安全算法时,人们倾向于谨慎行事。

So what hash function should I use in .NET?

那么我应该在 .NET 中使用什么哈希函数?

  • Use MD5 if you need the speed/size and don't care about birthday attacks or pre-image attacks.
  • 如果您需要速度/大小并且不关心生日攻击或原像攻击,请使用 MD5。

Repeat this after me, there are no chance MD5 collisions, malicious collisions can be carefully engineered. Even though there are no known pre-image attacks to date on MD5 the line from the security experts is that MD5 should not be used where you need to defend against pre-image attacks. SAME goes for SHA1.

在我之后重复这个,没有机会 MD5 冲突,可以精心设计恶意冲突。尽管迄今为止没有已知的 MD5 上的前映像攻击,但安全专家的说法是,不应该在需要防御前映像攻击的地方使用 MD5。同样适用于 SHA1

Keep in mind, not all algorithms need to defend against pre-image or collision attacks. Take the trivial case of a first pass search for duplicate files on your HD.

请记住,并非所有算法都需要防御原像或碰撞攻击。以首次通过搜索 HD 上的重复文件为例。

  • Use SHA2XX based function if you want a cryptographically secure hash function.
  • 如果您想要加密安全的哈希函数,请使用基于 SHA2XX 的函数。

No one ever found any SHA512 collision. EVER. They have tried really hard. For that matter no one ever found any SHA256 or 384 collision ever. .

没有人发现任何 SHA512 冲突。曾经。他们真的很努力。就此而言,从来没有人发现过任何 SHA256 或 384 冲突。.

  • Don't use SHA1 or RIPEMD unless its for an interoperability scenario.
  • 不要使用 SHA1 或 RIPEMD,除非用于互操作性场景。

RIPMED has not received the same amount of scrutiny that SHAX and MD5 has received. Both SHA1 and RIPEMD are vulnerable to birthday attacks. They are both slower than MD5 on .NET and come in the awkward 20 byte size. Its pointless to use these functions, forget about them.

RIPMED 没有受到与 SHAX 和 MD5 相同的。SHA1 和 RIPEMD 都容易受到生日攻击。它们都比 .NET 上的 MD5 慢,而且只有 20 字节大小。使用这些功能毫无意义,忘记它们吧。

SHA1 collision attacks are down to 2^52, its not going to be too long until SHA1 collisions are out in the wild.

SHA1 冲突攻击下降到 2^52,在 SHA1 冲突消失之前不会太久。

For up to date information about the various hash functions have a look at the hash function zoo.

有关各种散列函数的最新信息,请查看散列函数 zoo

But wait there is more

但是等等还有更多

Having a fasthash function can be a curse. For example: a very common usage for hash functions is password storage. Essentially, you calculate hash of a password combined with a known random string (to impede rainbow attacks) and store that hash in the database.

拥有快速散列函数可能是一种诅咒。例如:哈希函数的一个非常常见的用法是密码存储。本质上,您计算密码与已知随机字符串的哈希值(以阻止彩虹攻击)并将该哈希值存储在数据库中。

The problem is, that if an attacker gets a dump of the database, he can, quite effectively guess passwords using brute-force. Every combination he tries only takes a fraction of millisecond, and he can try out hundreds of thousands of passwords a second.

问题是,如果攻击者获得数据库的转储,他可以使用蛮力非常有效地猜测密码。他尝试的每一个组合只需要几分之一毫秒,他可以在一秒钟内尝试数十万个密码。

To work around this issue, the bcryptalgorithm can be used, it is designed to be slow so the attacker will be heavily slowed down if attacking a system using bcrypt. Recently scrypthas made some headline and is considered by some to be more effective than bcrypt but I do not know of a .Net implementation.

为了解决这个问题,可以使用bcrypt算法,它被设计为很慢,因此如果攻击使用 bcrypt 的系统攻击者将大大减慢速度。最近scrypt成为了一些头条新闻,有些人认为它比 bcrypt 更有效,但我不知道 .Net 实现。

回答by Florin Mircea

It would be a good ideea to take a look at the BLAKE2algorythm.

看看BLAKE2算法是个好主意。

As it is described, it is faster than MD5 and at least as secure as SHA-3. It is also implemented by several software applications, including WinRar.

正如所描述的,它比 MD5 更快,并且至少与 SHA-3 一样安全。它也由几个软件应用程序实现,包括 WinRar。