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

Sam*_*ron 135 .net c# hash cryptography cryptographic-hash-function

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

  • MD5:16字节(哈希时间500MB:1462毫秒)
  • SHA-1:20个字节(1644毫秒)
  • SHA256:32字节(5618毫秒)
  • SHA3​​84:48字节(3839毫秒)
  • SHA512:64字节(3820毫秒)
  • RIPEMD:20个字节(7066毫秒)

每个功能都有不同的表现; MD5是最快的,RIPEMD是最慢的.

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

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

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

我真的很想回答的具体问题是:

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

  • 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();
    }
Run Code Online (Sandbox Code Playgroud)

Eri*_*ett 136

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

  1. 碰撞阻力:有人找到两条散列相同的消息(任意两条消息)有多难.
  2. Preimage Resistance:给定哈希值,找到另一个哈希值相同的消息有多难?也称为单向散列函数.
  3. 第二个原像抗性:给定一条消息,找到另一个哈希相同的消息.

这些属性是相关但独立的.例如,碰撞阻力意味着第二前像素阻力,但不是相反.对于任何给定的应用程序,您将有不同的要求,需要这些属性中的一个或多个.用于保护服务器上的密码的哈希函数通常仅需要前映像素阻力,而消息摘要需要全部三个.

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

SHA1有一个缺陷,允许在理论上发现碰撞远远小于其长度的安全散列函数需要的2 ^ 80步.攻击不断被修改,目前可以在~2 ^ 63步骤中完成 - 几乎不在当前的可计算性范围内.因此,NIST正在逐步停止使用SHA1,并指出应在2010年之后使用SHA2系列.

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

RIPEMD我不能过多评论,除非注意它不像SHA系列那样常用,因此加密研究人员没有仔细检查.仅仅因为这个原因,我建议使用SHA函数.在您使用它的实现中,它似乎也很慢,这使它变得不那么有用.

总之,没有一个最好的功能 - 这一切都取决于你需要它.请注意每个方面的缺陷,您最好能够为您的方案选择正确的哈希函数.


Sam*_*ron 109

所有哈希函数都"破碎"

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

MD5/SHA1/Sha2xx没有机会碰撞

所有散列函数都有碰撞,这是生活中的事实.偶然发生这些碰撞相当于赢得了星系间的彩票.也就是说,没有人赢得星际彩票,这不是彩票的运作方式.永远不会遇到偶然的MD5/SHA1/SHA2XXX哈希值.每种语言中的每个单词,每种语言,都会散列到不同的值.整个星球上的每台机器上的每个路径名都有不同的MD5/SHA1/SHA2XXX哈希值.我怎么知道,你可能会问.好吧,正如我之前所说,从来没有人赢得星际彩票.

但是...... MD5坏了

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

目前,MD5 上没有已知的前映像或第二次前映像攻击.

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

尽管如此,如果您需要预映像电阻,目前的RSA建议不要使用MD5.在安全算法方面,人们往往会谨慎行事.

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

  • 如果您需要速度/大小并且不关心生日攻击或前映像攻击,请使用MD5.

在我之后重复这个,MD5没有碰撞的机会,可以精心设计恶意碰撞.尽管到目前为止MD5上还没有已知的预映像攻击,但安全专家认为MD5不应该用于需要防御前映像攻击的地方.SAME适用于SHA1.

请记住,并非所有算法都需要防御前映像或碰撞攻击.在第一遍搜索HD的重复文件的简单案例.

  • 如果需要加密安全散列函数,请使用基于SHA2XX的函数.

没有人发现任何SHA512碰撞.EVER.他们非常努力.就此而言,没有人发现任何SHA256或384碰撞..

  • 除非用于互操作性方案,否则不要使用SHA1或RIPEMD.

RIPMED没有收到SHAX和MD5收到的相同数量的审查.SHA1和RIPEMD都容易受到生日攻击.它们都比.NET上的MD5慢,并且具有笨拙的20字节大小.使用这些功能毫无意义,忘了它们.

SHA1碰撞攻击降低到2 ^ 52,它不会太长,直到SHA1碰撞在野外.

有关各种哈希函数的最新信息,请查看哈希函数zoo.

但等等还有更多

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

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

要解决此问题,可以使用bcrypt算法,它设计得很慢,因此如果使用bcrypt攻击系统,攻击者将会大大减速.最近scrypt已经成为一些标题,并被一些人认为比bcrypt更有效,但我不知道.Net实现.


Eth*_*man 35

更新:

时代变了,我们有一个SHA3冠军.我建议使用SHA3​​竞赛的keccak(aka SHA3)获胜者.

原答案:

为了最弱到最强,我会说:

  1. RIPEMD BROKEN,永远不能用,因为在这个pdf中可以看到
  2. MD-5 BROKEN,永远不能使用,可以在2分钟内用笔记本电脑打破
  3. SHA-1 BROKEN,永远不会被使用,原则上是破碎的,本周攻击越来越好
  4. SHA-2 WEAK,未来几年可能会破产.发现了一些弱点.请注意,通常密钥大小越高,哈希函数就越难破解.虽然密钥大小=强度并非总是如此,但大多数情况下都是如此.所以SHA-256可能比SHA-512弱.
  5. Skein NO KNOWN WEAKNESSES,是SHA-3的候选人.它是相当新的,因此未经测试.它已经用一堆语言实现.
  6. MD6 NO KNOWN WEAKNESSES,是SHA-3的另一个候选者.可能比Skien强,但在单核机器上速度较慢.像Skien一样,它是未经测试的.一些具有安全意识的开发人员正在使用它,担任关键任务角色.

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

  • 我不会把Skein和MD6列入榜单的高位; 有一个原因是SHA​​-3竞争将在2012年底之前完成.需要花费很长时间才能确信哈希函数实际上可能是安全的,并且这些功能都不是已经存在足够长的时间了. (5认同)
  • RIPEMD已损坏,但RIPEMD-128/160/256不同,并且没有损坏. (5认同)