大家好,我是阿赵。
这里分享个C#对称加密字符串的方法。
所谓的对称加密,意思是把原字符串通过秘钥,加密成另外一串字符串,然后可以通过秘钥还原回原字符串。
这种方法是基于Base64的,加密方法如下:
/// <summary>
/// 加密字符串
/// </summary>
/// <param name="str">需要加密的字符串</param>
/// <param name="encryptKey">加密key,长度4</param>
/// <returns></returns>
static public string Encrypt(string str, string encryptKey)
{
if(string.IsNullOrEmpty(str))
{
return str;
}
encryptKey = CheckEncryptKeyString(encryptKey,4);
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider(); //实例化加/解密类对象
byte[] key = Encoding.Unicode.GetBytes(encryptKey); //定义字节数组,用来存储密钥
byte[] data = Encoding.Unicode.GetBytes(str);//定义字节数组,用来存储要加密的字符串
MemoryStream MStream = new MemoryStream(); //实例化内存流对象
//使用内存流实例化加密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length); //向加密流中写入数据
CStream.FlushFinalBlock(); //释放加密流
return Convert.ToBase64String(MStream.ToArray());//返回加密后的字符串
}
这个方法支持加密key长度为4,如果长度不是4将会报错,所以这里加了一个检查key长度的方法,传入的长度是4,如果不够4,则补空格,如果超过4,则只取4个字符:
static public string CheckEncryptKeyString(string str,int len)
{
if(str.Length == len)
{
return str;
}
if(str.Length>len)
{
return str.Substring(0, len);
}
else
{
string newstr = str + new string(' ', len - str.Length);
return newstr;
}
}
下面是解密的方法:
/// <summary>
/// 解密字符串
/// </summary>
/// <param name="str">要解密的字符串</param>
/// <returns>解密后的字符串</returns>
static public string Decrypt(string str, string encryptKey)
{
if (string.IsNullOrEmpty(str))
{
return str;
}
encryptKey = CheckEncryptKeyString(encryptKey,4);
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider(); //实例化加/解密类对象
byte[] key = Encoding.Unicode.GetBytes(encryptKey); //定义字节数组,用来存储密钥
byte[] data = Convert.FromBase64String(str);//定义字节数组,用来存储要解密的字符串
MemoryStream MStream = new MemoryStream(); //实例化内存流对象
//使用内存流实例化解密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length); //向解密流中写入数据
CStream.FlushFinalBlock(); //释放解密流
return Encoding.Unicode.GetString(MStream.ToArray()); //返回解密后的字符串
}
第二种方法是在第一种方法的基础上做了一些修改,可以支持8位长度的秘钥:
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥,要求为8位</param>
/// <returns>加密成功返回加密后的字符串,失败返回null</returns>
public static string EncryptDES(string encryptString, string encryptKey)
{
try
{
encryptKey = CheckEncryptKeyString(encryptKey, 8);
byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(encryptKey);
byte[] rgbIV = rgbKey;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in mStream.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
catch
{
return null;
}
}
由于秘钥长度一定要是8位,不然会报错,所以还是继续用刚才判断的方法CheckEncryptKeyString,这次传入长度8。
下面是解密方法:
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返回null</returns>
public static string DecryptDES(string decryptString, string decryptKey)
{
try
{
decryptKey = CheckEncryptKeyString(decryptKey, 8);
byte[] rgbKey = ASCIIEncoding.ASCII.GetBytes(decryptKey);
byte[] rgbIV = rgbKey;
byte[] inputByteArray = new byte[decryptString.Length / 2];
for (int x = 0; x < decryptString.Length / 2; x++)
{
int i = (Convert.ToInt32(decryptString.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch(Exception ex)
{
return null;
}
}