125 lines
3.6 KiB
C#
125 lines
3.6 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
namespace HuanMeng.DotNetCore.WeChat
|
||
{
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public class WXBizDataCrypt
|
||
{
|
||
private string appId;
|
||
private string sessionKey;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="appId">小程序的 appId</param>
|
||
/// <param name="sessionKey">用户在小程序登录后获取的会话密钥</param>
|
||
public WXBizDataCrypt(string appId, string sessionKey)
|
||
{
|
||
this.appId = appId;
|
||
this.sessionKey = sessionKey;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检验数据的真实性,并且获取解密后的明文
|
||
/// </summary>
|
||
/// <param name="encryptedData">加密的用户数据</param>
|
||
/// <param name="iv">与用户数据一同返回的初始向量</param>
|
||
/// <param name="data">解密后的原文</param>
|
||
/// <returns>成功0,失败返回对应的错误码</returns>
|
||
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() { }
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public string? EncryptedData;
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public string? Iv;
|
||
|
||
|
||
public int UserId { get; set; }
|
||
}
|
||
|
||
}
|