using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json.Linq;
namespace HuanMeng.DotNetCore.WeChat
{
///
///
///
public class WXBizDataCrypt
{
private string appId;
private string sessionKey;
///
/// 构造函数
///
/// 小程序的 appId
/// 用户在小程序登录后获取的会话密钥
public WXBizDataCrypt(string appId, string sessionKey)
{
this.appId = appId;
this.sessionKey = sessionKey;
}
///
/// 检验数据的真实性,并且获取解密后的明文
///
/// 加密的用户数据
/// 与用户数据一同返回的初始向量
/// 解密后的原文
/// 成功0,失败返回对应的错误码
public int DecryptData(string encryptedData, string iv, out string data)
{
data = null;
// 检查 sessionKey 长度
if (sessionKey.Length != 24)
{
return ErrorCode.IllegalAesKey;
}
// 检查 iv 长度
if (iv.Length != 24)
{
return ErrorCode.IllegalIv;
}
try
{
byte[] aesKey = Convert.FromBase64String(sessionKey);
byte[] aesIV = Convert.FromBase64String(iv);
byte[] aesCipher = Convert.FromBase64String(encryptedData);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = aesKey;
aesAlg.IV = aesIV;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Padding = PaddingMode.PKCS7;
using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
{
using (MemoryStream msDecrypt = new MemoryStream(aesCipher))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// 解密后的明文
data = srDecrypt.ReadToEnd();
}
}
}
}
}
JObject dataObj = JObject.Parse(data);
// 检查 appId
if (dataObj["watermark"]["appid"].ToString() != this.appId)
{
return ErrorCode.IllegalBuffer;
}
return ErrorCode.OK;
}
catch
{
return ErrorCode.IllegalBuffer;
}
}
}
public static class ErrorCode
{
public const int OK = 0;
public const int IllegalAesKey = -41001;
public const int IllegalIv = -41002;
public const int IllegalBuffer = -41003;
}
public class WXBizDataCryptModel
{
public WXBizDataCryptModel() { }
///
///
///
public string? EncryptedData;
///
///
///
public string? Iv;
public int UserId { get; set; }
}
}