【问题标题】:How to Use SHA1 or MD5 in C#?(Which One is Better in Performance and Security for Authentication)如何在 C# 中使用 SHA1 或 MD5?(哪个在身份验证的性能和安全性方面更好)
【发布时间】:2010-12-17 21:22:47
【问题描述】:

在 C# 中我们如何自动使用 SHA1?
SHA1 比 MD5 更好吗?(我们对用户名和密码使用散列,并且需要速度进行身份验证)

【问题讨论】:

  • 我会建议 SHA1 加盐。
  • 我会建议 SHA256。 SHA1 现在被认为是弱的。
  • 我会建议 RIPEMD160。下面是如何在 C# 中使用它msdn.microsoft.com/en-us/library/…
  • 身份验证速度如何成为问题?即使使用密钥强化(您应该这样做!),身份验证仍将在数百毫秒内运行。此外,请务必使用每个用户的盐,这比 MD5 与 SHA 更重要。
  • 通常您希望密码散列的性能不佳。您通常使用减慢散列速度的方案来减缓蛮力攻击。

标签: c# .net authentication md5 sha1


【解决方案1】:

不确定您所说的自动是什么意思,但您确实应该使用SHA256 及更高版本。还 always use a Salt (code) 使用您的哈希值。附带说明一下,经过一段时间后,使用强化散列远比使用基于速度的普通散列函数好得多。即:散列数百次迭代,或使用已经证明的散列函数,例如bcrypt(我相信下面会提到)。在 .NET 中使用 SHA256 哈希函数的代码示例如下:

byte[] data = new byte[DATA_SIZE];
byte[] result;

using(SHA256 shaM = new SHA256Managed()) {
    result = shaM.ComputeHash(data);
}

将使用 SHA256 为您解决问题,地址为 MSDN


关于SHA1“破解”的旁注:Putting the cracking of SHA-1 in perspective

【讨论】:

  • @quantum - 当时这方面的信息没有现在那么多。删除了 SHA1 并添加了“透视 SHA1 的破解”的链接。
  • MD5 漏洞与密码无关。它允许攻击者创建一个冲突,前提是他知道原始明文。虽然这对于消息身份验证来说是一件非常糟糕的事情,但对于密码来说这不是问题。 (原始明文(希望)对攻击者不可用)。另一方面,请参阅nsa.unaligned.org 了解 SHA1 和 MD5 密码破解。请注意,他没有使用任何算法漏洞……他只是使用了 SHA1 和 MD5 速度快的事实。任何快速哈希算法(包括 SHA256)在没有密钥强化的情况下都容易受到攻击。
  • 我刚刚注意到这里现在是公认的答案。如果有人没有从我之前的评论中意识到这一点,那么像这样直接使用 SHA256 会在您的密码哈希中创建一个漏洞。它并不比 MD5 或 SHA1 好。没有人会使用 MD5 漏洞来破解您的密码。今天的暴力破解速度如此之快,你可以在一天内暴力破解整个 8 个字符序列。您需要选择比 SHA256、SHA1 和 MD5 慢的算法以保持安全。同样,通过迭代密钥来增强您的哈希算法,或者选择较慢的算法,例如 BCrypt 或 SCrypt。
  • @Kyle:我想我们说的是离线攻击。如果有人窃取了您的数据库,然后将其注入由 PS3、GPU 或 FPGA 构建的集群以破解密码。你不能谈论 SALTS(旨在防止 离线 彩虹表攻击),而不谈论密钥强化(旨在防止离线增量破解者攻击)
  • @Kyle:我认为,我们一直在谈论离线攻击。否则...我看不到所述的 MD5 和 SHA1 漏洞在何处与在线攻击有关。盐也与在线攻击无关......在在线攻击期间不可能使用彩虹表。
【解决方案2】:

SHA1 比 MD5 更强大,所以如果您有选择,最好使用它。这是一个例子:

public static string CalculateSHA1(string text, Encoding enc)
{
    byte[] buffer = enc.GetBytes(text);
    SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
    return BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
}

【讨论】:

  • 为什么要把“-”换成“”?
  • 这总是给我正确的哈希值,但在大写的情况下,这实际上不是正确的结果......知道吗?
  • 参见stackoverflow.com/a/5340599/44540BitConverter.ToString 返回一个十六进制字符串,它解释了连字符替换和大写问题。
  • 我认为 SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider(); 应该包含在 using 语句中,因为它的基类之一实现了 IDisposable
【解决方案3】:

两者都太快了,至少不能直接使用。使用密钥强化来“减慢”密码散列过程。不幸的是,速度是密码安全的敌人。

慢到什么程度才算慢?将密码哈希从 ~ 微秒减慢到 ~ 数百毫秒不会对应用程序的感知性能产生不利影响......但实际上会使破解密码的速度慢十万倍。

查看这篇文章了解详情: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

问题在于 MD5 速度很快。它的现代竞争对手也是如此,例如 SHA1 和 SHA256。速度是现代安全散列的设计目标,因为散列是几乎每个密码系统的构建块,并且通常在每个数据包或每个消息的基础上按需执行。

速度正是您在密码哈希函数中不想要的。

...剪断...

密码攻击游戏以破解密码 X 的时间计分。对于彩虹桌,该时间取决于您的桌需要多大以及搜索速度有多快。使用增量破解器,时间取决于您可以使密码哈希函数运行多快。

也就是说,使用 BCrypt。 SCrypt 是最近开发的,但我怀疑是否存在任何稳定的(或生产就绪的)库。从理论上讲,SCrypt 声称对 BCrypt 进行了改进。不建议“构建自己的”,但迭代 MD5 / SHA1 / SHA256 数千次应该可以解决问题(即:密钥强化)。

如果您不了解它们,请务必阅读 Rainbow Tables。基本的安全内容。

【讨论】:

    【解决方案4】:

    来自MSDN

    byte[] data = new byte[DATA_SIZE];
    byte[] result; 
    
    SHA1 sha = new SHA1CryptoServiceProvider(); 
    // This is one implementation of the abstract class SHA1.
    result = sha.ComputeHash(data);
    

    【讨论】:

      【解决方案5】:

      使用 SHA1 或 SHA2 MD5 算法有问题。

      http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5%28v=vs.85%29.aspx

      【讨论】:

        【解决方案6】:

        我想用这些东西。

        MD5、SHA1/256/384/512,带有可选的编码参数。

        其他 HashAlgorithms。感谢 Darin Dimitrov。

        public static string MD5Of(string text)
        {
            return MD5Of(text, Encoding.Default);
        }
        public static string MD5Of(string text, Encoding enc)
        {
            return HashOf<MD5CryptoServiceProvider>(text, enc);
        }
        public static string SHA1Of(string text)
        {
            return SHA1Of(text, Encoding.Default);
        }
        public static string SHA1Of(string text, Encoding enc)
        {
            return HashOf<SHA1CryptoServiceProvider>(text, enc);
        }
        
        public static string SHA384Of(string text)
        {
            return SHA384Of(text, Encoding.Default);
        }
        public static string SHA384Of(string text, Encoding enc)
        {
            return HashOf<SHA384CryptoServiceProvider>(text, enc);
        }
        
        public static string SHA512Of(string text)
        {
            return SHA512Of(text, Encoding.Default);
        }
        public static string SHA512Of(string text, Encoding enc)
        {
            return HashOf<SHA512CryptoServiceProvider>(text, enc);
        }
        
        public static string SHA256Of(string text)
        {
            return SHA256Of(text, Encoding.Default);
        }
        public static string SHA256Of(string text, Encoding enc)
        {
            return HashOf<SHA256CryptoServiceProvider>(text, enc);
        }
        
        public static string HashOf<TP>(string text, Encoding enc)
            where TP: HashAlgorithm, new()
        {
            var buffer = enc.GetBytes(text);
            var provider = new TP();
            return BitConverter.ToString(provider.ComputeHash(buffer)).Replace("-", "");
        }
        

        【讨论】:

          【解决方案7】:

          MD5 性能更好,SHA1 安全性更好。你可以从这个比较中得到一个想法

          【讨论】:

            猜你喜欢
            • 2023-03-21
            • 2019-12-29
            • 2013-05-18
            • 1970-01-01
            • 1970-01-01
            • 2010-10-02
            • 2015-12-18
            • 2012-06-20
            • 1970-01-01
            相关资源
            最近更新 更多