C#实现微信AES-128-CBC加解密数据
用C# (.NET Core 3.1 or above)实现微信或小程序AES-128-CBC加解密数据
直接上代码
其中引用的测试数据和Key来自 [https://git.weixin.qq.com/wxa_iot/deviceProtocol/blob/master/device_card_document.md]
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace console
{
/// <summary>
/// 实现微信AES-128-CBC加解密数据
/// </summary>
public class WXBizDataCrypt
{
/*
* [C#实现微信AES-128-CBC加密数据的解密](https://www.cnblogs.com/jetz/p/6384809.html)
*/
/// <summary>
/// AES解密
/// </summary>
/// <param name="text">带解密文本</param>
/// <param name="aesKey">密钥</param>
/// <param name="aesIV">16位初始向量</param>
/// <returns></returns>
public static string AESDecrypt(string text, string aesKey, string aesIV)
{
//16进制数据转换成byte
byte[] encryptedData = Convert.FromBase64String(text); // strToToHexByte(text);
using (var cipher = Aes.Create("AesManaged"))
{
cipher!.Key = Convert.FromBase64String(aesKey); // Encoding.UTF8.GetBytes(AesKey);
cipher.IV = Convert.FromBase64String(aesIV); // Encoding.UTF8.GetBytes(AesIV);
cipher.Mode = CipherMode.CBC;
cipher.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = cipher.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
string result = Encoding.Default.GetString(plainText);
return result;
}
}
/// <summary>
/// AES加密
/// reference to https://www.cnblogs.com/xyz0835/p/5775850.html
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static string AesEncrypt(string data, string aesKey, string aesIV)
{
byte[] keyBytes = Convert.FromBase64String(aesKey);
using (var cipher = Aes.Create("AesManaged"))
{
cipher!.Mode = CipherMode.CBC;
cipher.Padding = PaddingMode.PKCS7;
cipher.KeySize = 128;
cipher.BlockSize = 128;
cipher.Key = keyBytes;
cipher.IV = Convert.FromBase64String(aesIV);
byte[] valueBytes = Encoding.UTF8.GetBytes(data);
byte[] encrypted;
using (ICryptoTransform encryptor = cipher.CreateEncryptor())
{
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream writer = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
writer.Write(valueBytes, 0, valueBytes.Length);
writer.FlushFinalBlock();
encrypted = ms.ToArray();
var encryptedBase64 = Convert.ToBase64String(encrypted);
return encryptedBase64;
}
}
}
}
}
public static void Test()
{
var data = "{\"action\":\"fetch_device_state\",\"model_id\":\"xxx\",\"sn\":\"xxx\"}";
var sessionKey = "uIAxYsHTlCcnmJcaWP00Ig==";
var encryptedData =
"bOCfk9esztFBDvxP19s2WB679AtTWTZIUOQFHRJyCL/MF7iDi1MCFKrzkgtNNLRkDErpBBUGNpIVeAtMyCndgg==";
var iv = "xCxTwX7F/Hxq8o3LnGF27g==";
string decrypted = AESDecrypt(encryptedData, sessionKey, iv);
Console.WriteLine($"decrypted: {decrypted}");
Console.WriteLine(decrypted == data ? "decrypted succeed" : "decrypted failed");
string encrypted = AesEncrypt(data, sessionKey, iv);
Console.WriteLine($"encrypted: {encrypted}");
Console.WriteLine(encrypted == encryptedData ? "encrypted succeed" : "encrypted failed");
}
}
}
运行结果
扩展一下通过读取文件来加解密
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace console
{
class Program
{
static void Main(string[] args)
{
DecryptFromFile("encrypted_data.json");
EncryptFromFile("clear_data.json");
}
public static void DecryptFromFile(string fileName)
{
var sessionKey = "uIAxYsHTlCcnmJcaWP00Ig==";
var encryptedFileData = File.ReadAllText(fileName);
var node = JsonNode.Parse(encryptedFileData);
var encryptedData = (string)node!["encrypted_data"];
var iv = (string)node!["iv"];
var decrypted = WXBizDataCrypt.AESDecrypt(encryptedData, sessionKey, iv);
var deNode = JsonNode.Parse(decrypted);
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(deNode!.ToJsonString(options));
}
public static void EncryptFromFile(string fileName)
{
var sessionKey = "uIAxYsHTlCcnmJcaWP00Ig==";
var iv = "xCxTwX7F/Hxq8o3LnGF27g==";
var clearFileData = File.ReadAllText(fileName);
clearFileData = JsonNode.Parse(clearFileData)!.ToJsonString();
var encryptedData = WXBizDataCrypt.AesEncrypt(clearFileData, sessionKey, iv);
var node = new JsonObject()
{
["encrypted_data"] = encryptedData,
["iv"] = iv,
["encrypted_type"] = "AES/CBC/PKCS7Padding"
};
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(node!.ToJsonString(options));
}
}
}