最近在做物联网相关项目,数据推送是用AES加密的,但是在网上查找的资料没一个能用的,不是报错就是乱码......经过几个小时的修修改改后终于成功,在这里予以记录,希望给同样遇到此类问题的朋友一些帮助。
1、一定要明确AES算法的模式(这些在开发文档中会写),这个很重要!
AES算法有五种模式,这里不再列举,本文采用的是CBC模式,下面是解密代码:
/// <summary>
/// AES 算法解密(CBC模式) 先base64解码再解密,返回明文
/// </summary>
/// <param name="DecryptStr">密文</param>
/// <param name="Key">密钥</param>
/// <returns>明文</returns>
public static string AesDecryptor_Base64(string DecryptStr, string Key)
{
try
{
byte[] keyArray = encodeKey(Key);
byte[] decryptArray = Convert.FromBase64String(DecryptStr);
RijndaelManaged rDel = new RijndaelManaged();
rDel.Key = keyArray;
rDel.Mode = CipherMode.CBC;
rDel.Padding = PaddingMode.PKCS7;
rDel.IV = new byte[16];
ICryptoTransform cTransform = rDel.CreateDecryptor();
byte[] result = cTransform.TransformFinalBlock(decryptArray, 0, decryptArray.Length);
return Encoding.UTF8.GetString(result);
}
catch (Exception ex)
{
return null;
}
}
private static byte[] encodeKey(String password)
{
byte[] result = new byte[16]; for (int i = 0; i < 16; i++)
{
result[i] = 0;
}
byte[] passByte = Encoding.UTF8.GetBytes(password);
for (int i = 0; i < passByte.Length; i++)
{
if (i >= 16)
{
break;
}
result[i] = passByte[i];
}
return result;
}
这里我是先用到了Base64解码,再AES解密,不需要Base64解码的朋友记得修改byte[] decryptArray = Convert.FromBase64String(DecryptStr);这一行。
2、关于RijndaelManaged类的参数设置。
Key 就是密钥,要转换成Byte数组,长度必须为16,所以上面的encodeKey方法即是实现不足16位补0,超过16位取前16位的功能。
Mode 为AES算法的模式,模式选择不正确会乱码或者直接报错。我一开始不知道要选择这个,CBC模式的密文选择用ECB模式解密,直接报错。。。到这里不得不说句题外话,那个极其坑人的物联网平台的开发文档里压根都没有说要选择什么模式,还没有C#的Demo,最后我是硬着头皮在Java的Demo里面看到了CBC三个字母,想着试一下,嘿还真是。
Padding 为密文位数不足时补充的字符格式,也是看开发文档。(我同上是在Java的Demo里翻到的,哭死)
IV 属性真是最坑的一个,在网上找好多资料都没设置这个IV,我也没设置,但是在解密结果的前面总是有16位的乱码,乱码还一直在变,一直百思不得其解,后来实在没办法加上了这个属性,给了个16位的空字节数组,竟然就好了,所以我就是这样跟一个空数组斗智斗勇了两个小时。。。。
3、解密程序运行结果:
上面是加密的内容,下面是enc_msg字段进行解密后的结果。
加密的代码我没用到,所以就没写,有加密需要的朋友可以参考其他人的文档,需要注意的是,上面提到的那些参数,加密解密的时候要一致。
?
|