.Net加密解密
1.不可逆加密
平时使用最多的就是采用MD5加密,MD5实际上只是一种散列运算,或者可以称为单向的加密,即是说无法根据密文(加密后的数据),推导出明文(原数据)。不可逆加密有哪些作用呢?
- 防止文件被篡改
- 防止明文存储
- 防止抵赖,数字签名
- 急速秒传
MD5加密的代码实现:
#region MD5加密
//using System.Security.Cryptography;引入命名空間
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 stringBuilder = new StringBuilder();
switch (length)
{
case 16:
for (int i = 4; i < 12; i++)
{
stringBuilder.Append(hashValue[i].ToString("X2"));
}
break;
case 32:
for (int i = 0; i < 16; i++)
{
stringBuilder.Append(hashValue[i].ToString("X2"));
}
break;
default:
for (int i = 0; i < hashValue.Length; i++)
{
stringBuilder.Append(hashValue[i].ToString("x2"));
}
break;
}
return stringBuilder.ToString();
}
#endregion
#region MD5摘要
public static string AbstractFile(string fileName)
{
try
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(file);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
stringBuilder.Append(retVal[i].ToString("x2"));
}
return stringBuilder.ToString();
}
}
catch (Exception ex)
{
return ex.Message;
}
}
#endregion
前端使用:
string MD5=MD5Encrypt.Encrypt("123");
Console.WriteLine(MD5);
string MD516 = MD5Encrypt.Encrypt("123",16);
Console.WriteLine(MD516);
string MD5Other = MD5Encrypt.Encrypt("123",10);
Console.WriteLine(MD5Other);
//只要是相同的文件都產生相同的MD5摘要
string md5Abstract = MD5Encrypt.AbstractFile(@"H:\DZBStudyRecord\2018-5-28Encrypt\Encript\Encript\.Net中的加密解密.docx");
Console.WriteLine(md5Abstract);
2.对称可逆加密
对称加密的思路非常简单,就是含有一个称为密钥的东西,在消息发送前使用密钥对消息进行加密,在对方收到消息之后,使用相同的密钥进行解密。根据密钥来产生加密后的消息(密文)的这一加工过程,由加密算法来完成,加密算法通常是公开的。它的流程如下:
1. 发送方使用密钥对消息进行加密。
2. 接收方使用同样的密钥对消息进行解密。
可以使用下面一副图来表示:
对称加密存在这样两个问题:
1. 虽然可以通过密钥来保证消息安全地进行传递,但是如何确保密钥安全地进行传递?因为发送者和接收者总有一次初始的通信,用来传递密钥,此时的安全如何保证?
2. 接收者虽然可以根据密钥来解密消息,但因为存在上面的问题,消息有可能是由第三方(非法获得密钥)发来的,而接收方无法辨别。
这里介绍对称可逆加密的运用有很多,比如Des、AES、BlowFish:下面介绍Des加解密的代码实现:
首先封装一个Constain类,用来保存加密的字符串
/// <summary>
/// 一些固定的連接字符串的類
/// </summary>
public static class Constain
{
public static string DesKey = AppSettings("DesKey","Evan9796");
//通過該方法讀取App.Config中AppSettings的配置自由的改變我們的加密字符串
private static T AppSettings<T>(string DesKey, T defaultValue)
{
//引用using System.Configuration;命名空間
var value = ConfigurationManager.AppSettings[DesKey];
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
else
{
return (T)Convert.ChangeType(value, typeof(T));
}
}
}
加密解密的实现:
public class DesEncrypt
{
private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes(Constain.DesKey.Substring(0,8));
private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes(Constain.DesKey.Insert(0,"w").Substring(0,8));
/// <summary>
///加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string Encrypt(string str)
{
DESCryptoServiceProvider dESProvider = new DESCryptoServiceProvider();
using (MemoryStream stream = new MemoryStream())
{
CryptoStream cryptoStream = new CryptoStream(stream,dESProvider.CreateEncryptor(_rgbKey, _rgbIV),CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cryptoStream);
writer.Write(str);
writer.Flush();
cryptoStream.FlushFinalBlock();
stream.Flush();
return Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length);
}
}
/// <summary>
/// 解密
/// </summary>
/// <param name="Encryptstr"></param>
/// <returns></returns>
public static string Decrypt(string Encryptstr)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] buffer = Convert.FromBase64String(Encryptstr);
using (MemoryStream stream=new MemoryStream ())
{
CryptoStream cryptoStream = new CryptoStream(stream,des.CreateDecryptor(_rgbKey, _rgbIV),CryptoStreamMode.Write);
cryptoStream.Write(buffer, 0, buffer.Length);
cryptoStream.FlushFinalBlock();
return ASCIIEncoding.UTF8.GetString(stream.ToArray());
}
}
}
前端使用:
string deString = DesEncrypt.Encrypt("123");
Console.WriteLine(deString);
string enStrin = DesEncrypt.Decrypt(deString);
Console.WriteLine(enStrin);
3.非对称可逆加密
非对称加密的接收者和发送者都持有两个密钥,一个是对外公开的,称为公钥,一个是自行保管的,称为私钥。非对称加密的规则是由某人A的公钥加密的消息,只能由A的私钥进行解密;由A的私钥加密的消息只能由A的公钥解密。实际运用有RSA ECC,下面介绍RSA的实现。
public class RSAEncrypt
{
/// <summary>
/// 获取加密\解密对
/// </summary>
/// <returns></returns>
public static KeyValuePair<string,string> GetKeyPair()
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string publicKey = rsa.ToXmlString(false);
string privateKey = rsa.ToXmlString(true);
return new KeyValuePair<string, string>(publicKey, privateKey);
}
/// <summary>
/// 加密
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey"></param>
/// <returns></returns>
public static string Encrypt(string content, string encryptKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(encryptKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
/// <summary>
/// 解密
/// </summary>
/// <param name="content"></param>
/// <param name="decryptKey"></param>
/// <returns></returns>
public static string Decrypt(string content, string decryptKey)
{
byte[] dataToDecrypt = Convert.FromBase64String(content);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(decryptKey);
byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
return ByteConverter.GetString(resultBytes);
}
/// <summary>
/// 两组加密结合在一起
/// </summary>
/// <param name="content"></param>
/// <param name="publicKey"></param>
/// <param name="privateKey"></param>
/// <returns></returns>
private static string Encrypt(string content, out string publicKey, out string privateKey)
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ToXmlString(false);
privateKey = rsaProvider.ToXmlString(true);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
}
前端使用:
KeyValuePair<string, string> encryptDecrypt = RSAEncrypt.GetKeyPair();
string rsaEn1 = RSAEncrypt.Encrypt("net", encryptDecrypt.Key);//key是加密的
Console.WriteLine(rsaEn1);
string rsaDe1 = RSAEncrypt.Decrypt(rsaEn1, encryptDecrypt.Value);//value
Console.WriteLine(rsaDe1);
4. .NET中加密解密的支持
.NET中也提供了两组类用于加密解密,一组为对称加密,一组为非对称加密,如下图所示: