欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c#加密:二、散列法 MD5、SHA256、SHA512

程序员文章站 2024-03-19 14:14:52
...

        散列法提供了一种单向加密的方式。这种方式非常适用于在数据库中存储密码。因为我们无须(也不希望)提供解密的信息。在登录验证时,只需简单地将用户的输入进行散列,并和数据库中存储的散列值进行比较即可。

        由于散列码的长度不会随着源数据的长度而变化,因此可用于文件比较和数据流错误检查(和校验码非常类似)。源数据中任意一个位的变化都能够使散列码发生巨大的变化。

        HashAlgorithm子类(例如SHA256或者MD5)的ComputeHash方法可以用于生成散列码:

        获取文件的MD5

byte[] hash;
using (Stream fa = File.OpenRead("text_file1.txt"))
{
    hash = MD5.Create().ComputeHash(fa);
}

         对字符串进行SHA256加密

byte[] data = System.Text.Encoding.UTF8.GetBytes("this is a password");
byte[] hash256 = SHA256.Create().ComputeHash(data);

        Encoding类的GetBytes方法将会把字符串编码为字节数组;而Get-String方法则会执行反向操作。但是Encoding类无法将一个加密或者散列之后的字节数组转换为字符串,因为这种数据往往会包含违反编码规则的数据。如果需要将字节数组转换为合法的(且XML友好的)字符串,或执行相反操作,请分别使用Convert.ToBase64String和Convert.From-Base64String。

        MD5和SHA256是.NET Framework中从HashAlgorithm派生的子类。以下以升序按照安全等级列出了常用的散列算法: 

MD5(16)->SHA1(20)->SHA256(32)->SHA384(48)->SHA512(64)

        算法的长度越短运算的速度越快。MD5的运算速度比SHA512快20多倍,因此非常适用于计算文件的校验和。MD5算法可以每秒钟加密数百兆字节的数据,并将其存储在一个Guid中(Guid恰好也是16字节长,并且作为一个值类型比字节数组更易于处理。例如,我们可以直接用相等运算符比较两个Guid的值。)但同时,越短的散列算法发生碰撞(两个不同的文件会生成相同的散列码)的概率越大。

        如果要存储密码或其他高安全等级的敏感数据,请至少使用SHA256。MD5和SHA1在这种情形下是不安全的。MD5和SHA1仅适用于防止意外的破坏,而无法防御故意的篡改行为。 

        SHA384执行速度并不比SHA512快,因此如果需要获取比SHA256更高的安全性,可以使用SHA512。较长的SHA算法可以用于密码的散列。但是它们需要强制采用高密码强度的策略来防范字典攻击的威胁(字典攻击指攻击者对字典中的每一个词进行散列,创建一个密码查找表的攻击策略)。还可以通过重复散列的方式来加长密码散列值的长度,从而提供更强的保护。例如,如果重复进行100次散列,则使用字典攻击需要花费1个月来**的密码现在需要8年才能够**。Rfc2898DeriveBytes和PasswordDeriveBytes类恰好提供了上述功能。

        另一种防止字典攻击的技术是在加密过程中引入salt“盐”,即由随机数生成器生成的一长串字节,并在散列之前将其并入密码中。这样做可以通过两种途径来对抗攻击者:

        1、这需要更长的计算时间,

        2、攻击者无法访问“盐”字节的值。

        此外,Framework还提供了160位的RIPEMD散列算法。这种算法的安全性比SHA1稍好,但受制于.NET对该算法的低效实现,它的执行速度比SHA512还慢。