我们经常在开发中要对字符串进行加密,解密,下面是我经常用到的DES加密和解密方法,可以根据自己的需求选择DES的不同加密模式和填充模式,这里提供两种加密结果方法,一种是返回HEX加密字符串,这个字符串不包含特殊字符,密文全部是由字母和数字组成,非常适用某些特殊场景,也是我特别喜欢的一种加密结果,不需要考虑特殊字符问题;还一种就是最常见的加密结果Base64字符串,不多说了,直接上代码
/// <summary>
/// 文章来源于成长的小猪
/// http://blog.csdn.net/jasonsong2008
/// </summary>
[TestFixture()]
public class DesHelperTests
{
//待加密的字符串
const string Str = "成长的小猪(Jason.Song)http://blog.csdn.net/jasonsong2008 ";
//密钥(限定8位任意字符)用于加解密
const string Key = "jason!@#";
/// <summary>
/// 加解密测试(Hex)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// 此加密方法生成 Hex 字符串,这个有点好就是加密后字符串中不包含特殊字符,适用于特殊场景
/// </summary>
[Test()]
public void EncryptToHexStringTest() {
var ciphertext = DesHelper.EncryptToHexString(Str, Key, Encoding.UTF8);
//var ciphertext = DesHelper.EncryptToHexString(str, key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
Console.Out.WriteLine(ciphertext);
//加密后输出结果如下
//754B1591AEDD6056545731496E78E335554746E7F2A8F95C28228420DD3A6F701F8E708E2601B673416455E30065FE1FD75E36494A6910DD03BE3413170F732783361E15BCFCD4B8
//解密方法
var plaintext = DesHelper.DecryptByHexString(ciphertext, Key, Encoding.UTF8);
//var plaintext = DesHelper.DecryptByHexString(ciphertext, key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
Console.Out.WriteLine(plaintext);
Assert.AreEqual(Str, plaintext);
}
/// <summary>
/// 加解密测试(Base64)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// 此加密方法生成 Base64 字符串,该用法最常见
/// </summary>
[Test()]
public void EncryptToBase64StringTest() {
//加密方法
var ciphertext = DesHelper.EncryptToBase64String(Str, Key, Encoding.UTF8);
//var ciphertext = DesHelper.EncryptToBase64String(Str, Key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
Console.Out.WriteLine(ciphertext);
//加密后输出结果如下
//dUsVka7dYFZUVzFJbnjjNVVHRufyqPlcKCKEIN06b3AfjnCOJgG2c0FkVeMAZf4f1142SUppEN0DvjQTFw9zJ4M2HhW8/NS4
//解密方法
var plaintext = DesHelper.DecryptByBase64String(ciphertext, Key, Encoding.UTF8);
//var plaintext = DesHelper.DecryptByBase64String(ciphertext, Key, Encoding.UTF8, CipherMode.CBC, PaddingMode.PKCS7);
Console.Out.WriteLine(plaintext);
Assert.AreEqual(Str, plaintext);
}
}
下面是DES的加密解密类
/// <summary>
/// DES加解密
/// Add by 成长的小猪(Jason.Song) on 2017/11/20
/// http://blog.csdn.net/jasonsong2008
///
/// DES是对称性加密里面常见一种,全称为Data Encryption Standard,即数据加密标准,
/// 是一种使用密钥加密的块算法。密钥长度是64位(bit),超过位数密钥被忽略。
/// 所谓对称性加密,加密和解密密钥相同。对称性加密一般会按照固定长度,把待加密字符串分成块。
/// 不足一整块或者刚好最后有特殊填充字符。往往跨语言做DES加密解密,经常会出现问题。
/// 往往是填充方式不对、或者编码不一致、或者选择加密解密模式(ECB,CBC,CTR,OFB,CFB,NCFB,NOFB)没有对应上造成。
/// 常见的填充模式有: 'pkcs5','pkcs7','iso10126','ansix923','zero' 类型,
/// 包括DES-ECB,DES-CBC,DES-CTR,DES-OFB,DES-CFB。
/// </summary>
public static class DesHelper
{
#region DES 加密
/// <summary>
/// 加密(Hex)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥(8位任意字符)</param>
/// <param name="encoding">字符编码</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static string EncryptToHexString(string encryptString, string encryptKey, Encoding encoding,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
//为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
//var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
var keyBytes = encoding.GetBytes(encryptKey);
var inputBytes = encoding.GetBytes(encryptString);
var outputBytes = EncryptToDesBytes(inputBytes, keyBytes, cipher, padding);
var sBuilder = new StringBuilder();
foreach (var b in outputBytes) {
sBuilder.Append(b.ToString("X2"));
}
return sBuilder.ToString();
}
/// <summary>
/// 加密(Base64)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥(8位任意字符)</param>
/// <param name="encoding">字符编码</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static string EncryptToBase64String(string encryptString, string encryptKey, Encoding encoding,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
//为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
//var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
var keyBytes = encoding.GetBytes(encryptKey);
var inputBytes = encoding.GetBytes(encryptString);
var outputBytes = EncryptToDesBytes(inputBytes, keyBytes, cipher, padding);
return Convert.ToBase64String(outputBytes);
}
/// <summary>
/// 加密
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="encryptBytes">待加密的字节数组</param>
/// <param name="keyBytes">加密密钥字节数组</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static byte[] EncryptToDesBytes(byte[] encryptBytes, byte[] keyBytes,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
var des = new DESCryptoServiceProvider {
Key = keyBytes,
IV = keyBytes,
Mode = cipher,
Padding = padding
};
var outputBytes = des.CreateEncryptor().TransformFinalBlock(encryptBytes, 0, encryptBytes.Length);
return outputBytes;
}
#endregion
#region DES 解密
/// <summary>
/// 解密(Hex)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥(8位任意字符)</param>
/// <param name="encoding">字符编码</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static string DecryptByHexString(string decryptString, string decryptKey, Encoding encoding,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
//为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
//var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
var keyBytes = encoding.GetBytes(decryptKey);
var inputBytes = new byte[decryptString.Length / 2];
for (var i = 0; i < inputBytes.Length; i++) {
inputBytes[i] = Convert.ToByte(decryptString.Substring(i * 2, 2), 16);
}
var outputBytes = DecryptByDesBytes(inputBytes, keyBytes, cipher, padding);
return encoding.GetString(outputBytes).TrimEnd('\0');
}
/// <summary>
/// 解密(Base64)
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥(8位任意字符)</param>
/// <param name="encoding">字符编码</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static string DecryptByBase64String(string decryptString, string decryptKey, Encoding encoding,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
//为了安全级别更高,这个地方建议将密钥进行MD5后取8位,这里我就不加此方法啦
//var keyBytes = encoding.GetBytes(Md5Helper.GetMd5HashString(encryptKey, encoding).Substring(0, 8));
var keyBytes = encoding.GetBytes(decryptKey);
var inputBytes = Convert.FromBase64String(decryptString);
var outputBytes = DecryptByDesBytes(inputBytes, keyBytes, cipher, padding);
return encoding.GetString(outputBytes).TrimEnd('\0');
}
/// <summary>
/// 解密
/// Add by 成长的小猪(Jason.Song) on 2017/07/26
/// </summary>
/// <param name="decryptBytes">待解密的字节数组</param>
/// <param name="keyBytes">解密密钥字节数组</param>
/// <param name="cipher">运算模式</param>
/// <param name="padding">填充模式</param>
/// <returns></returns>
public static byte[] DecryptByDesBytes(byte[] decryptBytes, byte[] keyBytes,
CipherMode cipher = CipherMode.ECB, PaddingMode padding = PaddingMode.Zeros) {
var des = new DESCryptoServiceProvider {
Key = keyBytes,
IV = keyBytes,
Mode = cipher,
Padding = padding
};
var outputBytes = des.CreateDecryptor().TransformFinalBlock(decryptBytes, 0, decryptBytes.Length);
return outputBytes;
}
#endregion
}