MD5加密的基本常识和封装类
MD5加密的基本常识和封装类
MD5(Message Digest Algorithm 5)是一种常见的哈希算法,用于将任意长度的数据转换为固定长度的(通常是128位或16字节)哈希值。它是MD家族中的第五个算法,广泛用于数据校验、数字签名、密码存储等领域。MD5是单向函数,即无法从生成的哈希值反推出原始数据,这也是其常用于对敏感信息进行加密或签名的原因之一。
1. MD5的原理
MD5算法的核心原理是基于位操作、逻辑运算和模运算,对输入的数据进行多轮循环处理,生成最终的128位哈希值。具体步骤如下:
-
填充数据: 将原始数据填充至512位的倍数(64字节)。
-
初始值: 初始化4个32位的寄存器(A、B、C、D),用作哈希的中间结果。
-
分组处理: 将填充后的数据分成512位(64字节)的分组,每个分组进行下面的处理。
-
循环压缩: 将每个分组进行四轮循环压缩,每轮循环使用不同的非线性函数(F、G、H、I)和常量。
-
合并结果: 将每个分组经过四轮循环压缩后的中间结果与初始值相加,得到新的中间结果。
-
输出: 最后,将四个寄存器的内容按照从低位到高位的顺序连接起来,得到128位的MD5哈希值。
2. MD5的应用
MD5在计算机领域有广泛的应用,包括但不限于以下几个方面:
-
数据完整性校验: 在数据传输过程中,使用MD5计算数据的哈希值,接收方根据接收到的数据和哈希值重新计算哈希值,并与接收到的哈希值进行对比,以验证数据的完整性和是否被篡改。
-
数字签名: 在数字签名中,对原始数据使用MD5进行哈希计算,然后使用私钥对哈希值进行加密生成数字签名。接收方使用公钥解密数字签名,再对原始数据进行MD5哈希计算,并与解密后的签名对比,以验证数据的来源和完整性。
-
密码存储: 在密码存储中,不应该将明文密码直接存储在数据库中,而是将密码进行MD5哈希后再存储。用户登录时,输入的密码也进行MD5哈希后与数据库中存储的哈希值进行比较,从而验证密码是否正确。
-
防篡改校验: 在软件发布过程中,可以对软件文件进行MD5哈希计算,并将哈希值与官方发布的哈希值进行比较,从而验证软件是否被篡改。
需要注意的是,由于MD5算法的特性,它已经不再被认为是一种安全的哈希算法。因为MD5容易受到碰撞攻击(collision attack),即找到两个不同的输入数据,经过MD5计算后得到相同的哈希值。因此,在安全性要求较高的场景下,应该使用更强大、不易受到碰撞攻击的哈希算法,如SHA-256或SHA-3。
3. MD5加密封装类
/// <summary>
/// 不可逆加密
/// 1 防止被篡改
/// 2 防止明文存储
/// 3 防止抵赖,数字签名
/// </summary>
public class MD5Encrypt
{
#region MD5
/// <summary>
/// MD5加密,和动网上的16/32位MD5加密结果相同,
/// 使用的UTF8编码
/// </summary>
/// <param name="source">待加密字串</param>
/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
/// <returns>加密后的字串</returns>
public static string Encrypt(string source, int length = 32)//默认参数
{
if (string.IsNullOrEmpty(source)) return string.Empty;
HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
byte[] bytes = Encoding.UTF8.GetBytes(source);//这里需要区别编码的
byte[] hashValue = provider.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
switch (length)
{
case 16://16位密文是32位密文的9到24位字符
for (int i = 4; i < 12; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
case 32:
for (int i = 0; i < 16; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
default:
for (int i = 0; i < hashValue.Length; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
}
return sb.ToString();
}
#endregion MD5
#region MD5摘要
/// <summary>
/// 获取文件的MD5摘要
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string AbstractFile(string fileName)
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
return AbstractFile(file);
}
}
/// <summary>
/// 根据stream获取文件摘要
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string AbstractFile(Stream stream)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
#endregion
}