在C#开发中,遇到AES加密,解密问题,因此,在这里记录一下,
该方法默认以下模式:
Mode:CBC
Padding:PKCS7
方法支持:
1.AES加密,返回base64的密文
string msg = AESHelper.AESEncrypt("待加密内容","key","v");
2.AES解密,返回utf-8的明文
string msg = AESHelper.AESEncrypt2("待加密内容","key","v");
代码类如下:
/// <summary>
/// AES 加密、解密
/// </summary>
public class AESHelper
{
#region AES加密,返回base64的密文
/// <summary>
/// <para>Describe:AES加密,返回base64的密文</para>
/// <para>Author:KAI</para>
/// </summary>
/// <param name="toEncrypt">源数据</param>
/// <param name="key">密钥</param>
/// <param name="iv">向量</param>
/// <returns>base64的密文</returns>
public static string AESEncrypt(string toEncrypt, string key, string iv)
{
byte[] keyArray = ConvertToByteAndAppend0(key, 24);
byte[] ivArray = ConvertToByteAndAppend0(iv, 16);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.IV = ivArray;
rDel.Mode = CipherMode.CBC;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static byte[] ConvertToByteAndAppend0(string value, int intLength)
{
byte[] valueArray = new byte[intLength];
byte[] temp = UTF8Encoding.UTF8.GetBytes(value);
for (int i = 0; i < temp.Length; i++)
{
valueArray[i] = temp[i];
}
for (int i = temp.Length; i < intLength; i++)
{
valueArray[i] = 0x0;
}
return valueArray;
}
#endregion
#region AES解密,返回utf-8的明文
/// <summary>
/// <para>Describe:AES解密,返回utf-8的明文</para>
/// <para>Author:KAI</para>
/// </summary>
/// <param name="toEncrypt">密文</param>
/// <param name="key">密钥</param>
/// <param name="iv">向量</param>
/// <returns>utf-8的明文</returns>
public static string AESEncrypt2(string toDecrypt, string key, string iv)
{
byte[] keyArray = ConvertToByteAndAppend0(key, 24);
byte[] ivArray = ConvertToByteAndAppend0(iv, 16);
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.IV = ivArray;
rDel.Mode = CipherMode.CBC;
rDel.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
string f = UTF8Encoding.UTF8.GetString(resultArray);
return UTF8Encoding.UTF8.GetString(resultArray);
}
#endregion
#region AES解密
/// <summary>
/// 解密
/// </summary>
/// <param name="encryptResultStr">待解密的密文字</param>
/// <param name="decryptKey">解密的key</param>
/// <returns>解密后的字符串</returns>
public static string AesDecrypt(String encryptResultStr, String decryptKey)
{
//base64 decode
String decrpt = EbotongDecrypto(encryptResultStr);
//hexStr to Str
byte[] decryptFrom = ParseHexStr2Str(decrpt);
//
return decrypt(decryptFrom, decryptKey);
}
/// <summary>
/// Base64解密
/// </summary>
/// <param name="result">待解密的密文</param>
/// <returns>解密后的字符串</returns>
public static string EbotongDecrypto(string result)
{
string decode = "";
byte[] bytes = Convert.FromBase64String(result);
try
{
decode = Encoding.UTF8.GetString(bytes);
}
catch
{
decode = result;
}
return decode;
}
/// <summary>
/// 16进制字符串转字符串
/// </summary>
/// <param name="hexStr">16进制字符串</param>
/// <returns>转换后的字符串</returns>
public static byte[] ParseHexStr2Str(String hexStr)
{
if (hexStr == null || hexStr.Length < 1)
return null;
byte[] result = new byte[hexStr.Length / 2];
String s = "";
for (int i = 0; i < hexStr.Length / 2; i++)
{
s = hexStr.Substring(i * 2, 1);
int high = Convert.ToInt32(s, 16);
s = hexStr.Substring(i * 2 + 1, 1);
int low = Convert.ToInt32(s, 16);
result[i] = (byte)(high * 16 + low);
}
return result;
}
/// <summary>
/// 解密
/// </summary>
/// <param name="toDecrypt">待解密的密文字节数组</param>
/// <param name="key">解密的key</param>
/// <returns>解密后的字符串</returns>
public static string decrypt(byte[] toDecrypt, string key)
{
//需要注意几点:
//1)C#默认运算模式为CBC,java默认为ECB,因此要将C#的加密方式改为ECB
//2)C#的Padding方式要设置为PaddingMode.PKCS7,否则解密出来后结尾可能有乱码
//key = "cGh19CbAIehVxt5ZqRDBJw==";
byte[] keyArray = Convert.FromBase64String(key);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.ECB;//必须设置为ECB
rDel.Padding = PaddingMode.PKCS7;//必须设置为PKCS7
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toDecrypt, 0, toDecrypt.Length);
return UTF8Encoding.UTF8.GetString(resultArray);
}
#endregion
}