C#实现加密与解密详解
作者:springsnow 时间:2023-08-11 16:54:42
一、Hash加密,使用HashAlgorithm哈希算法类的派生类(MD5、SHA1等)
特点:只能加密,不可逆。可对目标信息生成一段特定长度唯一的Hash值。
HashAlgorithm派生类包括:
KeyedHashAlgorithm: 显示所有加密哈希算法实现均必须从中派生的抽象类。
MD5: 表示 MD5 哈希算法的所有实现均从中继承的抽象类。
————MD5CryptoServiceProvider:使用加密服务提供程序 (CSP) 提供的实现,计算输入数据的 MD5 哈希值。RIPEMD160: 表示 MD160 哈希算法的所有实现均从中继承的抽象类。
SHA1: 计算输入数据的 SHA1 哈希值。
————SHA1CryptoServiceProvider:使用加密服务提供程序 (CSP) 提供的实现,计算输入数据的 SHA1 哈希值。SHA256: 计算输入数据的 SHA256 哈希值。
SHA384: 计算输入数据的 SHA384 哈希值。
SHA512: 计算输入数据的 SHA512 哈希值。
1、使用抽象类HashAlgorithm
//明文密码由字符串转换为byte数组
byte[] clearBytes =Encoding.Default.GetBytes("123");
//由明文的byte数组计算出MD5密文byte数组
byte[] hashedBytes = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(clearBytes);
//把byte数组转换为字符串后返回,BitConverter用于将基础数据类型与字节数组相互转换
string result = BitConverter.ToString(hashedBytes).Replace("-", "");
Console.Write(result);
2、使用抽象类MD5
byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes = MD5.Create().ComputeHash(clearBytes);
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < hashedBytes.Length; i++)
{
sBuilder.Append(hashedBytes[i].ToString("x2"));
}
string result = sBuilder.ToString();
Console.Write(result);
3、使用MD5CryptoServiceProvider类
byte[] clearBytes = Encoding.Default.GetBytes("123");
byte[] hashedBytes = new MD5CryptoServiceProvider().ComputeHash(clearBytes);
string result = "";
for (int i = 0; i < hashedBytes.Length; i++)
result += hashedBytes[i].ToString("X").PadLeft(2, '0');
Console.Write(result);
4、Web使用的Hash加密:FormsAuthentication类
FormAuthentication.HashPasswordForStoringInConfigFile(str,"MD5")//或者“SHA1”
5、文件哈希计算
MD5是一个将任意长度的数据字符串转化成短的固定长度的值的单向操作。任意两个字符串不应有相同的散列值(即,有“很大可能”是不一样的,并且要人为地创造出来两个散列值相同的字符串应该是困难的)。
因此MD5经常用于校验字符串或者文件,因为如果文件的MD5不一样,说明文件内容也是不一样的,即经过修改的,如果发现下载的文件和给的md5值不一样,就需要慎重使用。
MD5文件校验用途非常多,例如:游戏patch包的校验,病毒文件确认,app提审校验等等,只要需要确认某一个文件的唯一性和正确性,都会使用md5作为校验。
输入文件路径,就可以得到对应的哈希值,这个哈希值是对文件本身内容包括文件名字有关,跟文件存放的路径和运行平台,设备无关。
string GetFileHash(string path)
{
var hash = MD5.Create();//SHA1.Create();
var stream = new FileStream(path, FileMode.Open);
byte[] hashByte = hash.ComputeHash(stream);
stream.Close();
return BitConverter.ToString(hashByte).Replace("-", "");
}
二、对称加密:使用SymmetricAlgorithm对称算法类的派生类(Aes、DES等)
特点:指加密和解密使用相同密钥的加密算法。
对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。
SymmetricAlgorithm派生类包括:
Aes:表示高级加密标准 (AES) 的所有实现都必须从中继承的抽象基类。
————AesCryptoServiceProvider:使用高级加密标准 (AES) 算法的加密应用程序编程接口 (CAPI) 实现来执行对称加密和解密。DES:表示所有 DES 实现都必须从中派生的数据加密标准 (DES) 算法的基类。
————DESCryptoServiceProvider:定义访问数据加密标准 (DES) 算法的加密服务提供程序 (CSP) 版本的包装对象。RC2:表示 RC2 算法的所有实现都必须从中派生的基类。
Rijndael:表示 Rijndael 对称加密算法的所有实现必须从其继承的基类。
TripleDES:表示三重数据加密标准算法的基类
public static string strKey = "abcdefgh";//注意:这里的密钥sKey必须能转为8个byte,即输入密钥为8半角个字符或者4个全角字符或者4个汉字的字符串
public static string strIV = "ijklmnop";
// 加密
public static string Encrypt(string _strQ)
{
byte[] buffer = Encoding.UTF8.GetBytes(_strQ);
MemoryStream ms = new MemoryStream();
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
CryptoStream encStream = new CryptoStream(ms, des.CreateEncryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
encStream.Write(buffer, 0, buffer.Length);
encStream.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
// 解密
public static string Decrypt(string _strQ)
{
byte[] buffer = Convert.FromBase64String(_strQ);
MemoryStream ms = new MemoryStream();
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
CryptoStream encStream = new CryptoStream(ms, des.CreateDecryptor(Encoding.UTF8.GetBytes(strKey), Encoding.UTF8.GetBytes(strIV)), CryptoStreamMode.Write);
encStream.Write(buffer, 0, buffer.Length);
encStream.FlushFinalBlock();
return Encoding.UTF8.GetString(ms.ToArray());
}
三、非对称加密:使用AsymmetricAlgorithm非对称算法类的派生类(DSA、RSA等)
特点:指加密和解密使用不同密钥的加密算法,也称为公私钥加密。公钥是可以公开用来加密,私匙严格由接受方保密用于加密。
非对称加密的缺点是加解密速度要远远慢于对称加密。
AsymmetricAlgorithm派生类包括:
DSA:表示数字签名算法(DSA)的所有实现都必须从中继承的抽象基类。
————DSACryptoServiceProvider:使用加密服务提供程序 (CSP) 提供的 DSA算法的实现执行不对称加密和解密。ECDiffieHellman:
ECDsa:
RSA:表示 RSA 算法的所有实现均从中继承的基类。
————RSACryptoServiceProvider:使用加密服务提供程序 (CSP) 提供的 RSA 算法的实现执行不对称加密和解密。
///
/// 获取加密所使用的key,RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。
///
public static void GetKey()
{
string PublicKey = string.Empty;
string PrivateKey = string.Empty;
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
PublicKey = rSACryptoServiceProvider.ToXmlString(false);
// 获取公匙,用于加密
PrivateKey = rSACryptoServiceProvider.ToXmlString(true);
// 获取公匙和私匙,用于解密
//Console.WriteLine("PublicKey is {0}", PublicKey); // 输出公匙
//Console.WriteLine("PrivateKey is {0}", PrivateKey); // 输出密匙
//密匙中含有公匙,公匙是根据密匙进行计算得来的。
using (StreamWriter streamWriter = new StreamWriter("PublicKey.xml"))
{
streamWriter.Write(rSACryptoServiceProvider.ToXmlString(false));// 将公匙保存到运行目录下的PublicKey
}
using (StreamWriter streamWriter = new StreamWriter("PrivateKey.xml"))
{
streamWriter.Write(rSACryptoServiceProvider.ToXmlString(true)); // 将公匙&私匙保存到运行目录下的PrivateKey
}
}
///
/// 加密
///
private static string Encryption(string str)
{
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
using (StreamReader streamReader = new StreamReader("PublicKey.xml")) // 读取运行目录下的PublicKey.xml
{
rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 将公匙载入进RSA实例中
}
byte[] buffer = Encoding.UTF8.GetBytes(str); // 将明文转换为byte[]
// 加密后的数据就是一个byte[] 数组,可以以 文件的形式保存 或 别的形式(网上很多教程,使用Base64进行编码化保存)
byte[] EncryptBuffer = rSACryptoServiceProvider.Encrypt(buffer, false); // 进行加密
return Convert.ToBase64String(EncryptBuffer); // 如果使用base64进行明文化,在解密时 需要再次将base64 转换为byte[]
}
///
/// 解密
///
private static string Decrypt(string strEncryptBase64)
{
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
using (StreamReader streamReader = new StreamReader("PrivateKey.xml")) // 读取运行目录下的PrivateKey.xml
{
rSACryptoServiceProvider.FromXmlString(streamReader.ReadToEnd()); // 将私匙载入进RSA实例中
}
byte[] buffer = Convert.FromBase64String(strEncryptBase64);
// 解密后得到一个byte[] 数组
byte[] DecryptBuffer = rSACryptoServiceProvider.Decrypt(buffer, false); // 进行解密
string str = Encoding.UTF8.GetString(DecryptBuffer); // 将byte[]转换为明文
return str;
}
来源:https://www.cnblogs.com/springsnow/p/12557009.html