using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System; using System.IO; using System.Security.Cryptography; using System.Text; using YD_XinWei.Api.WeChat.Lib; namespace YD_XinWei.Api.WeChat { /// /// 微信小程序登录接口 /// public class WeChatAppDecrypt { //public IConfiguration Configuration { get; } /// /// 构造函数 /// /// //public WeChatAppDecrypt(IConfiguration configuration) //{ // Configuration = configuration; //} public WeChatAppDecrypt() { } /// /// 获取OpenId和SessionKey的Json数据包 /// /// 客户端发来的code /// Json数据包 private string GetOpenIdAndSessionKeyString(string code, string appid, string secret) { //string temp = "https://api.weixin.qq.com/sns/jscode2session?" + // "appid=" + Configuration["Wechat:APPID"] // + "&secret=" + Configuration["Wechat:APPSECRET"] // + "&js_code=" + code // + "&grant_type=authorization_code"; string temp = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code"; return HttpService.Get(temp); } /// /// 反序列化包含OpenId和SessionKey的Json数据包 /// /// Json数据包 /// 包含OpenId和SessionKey的类 public OpenIdAndSessionKey DecodeOpenIdAndSessionKey(WechatLoginInfo loginInfo) { var res = GetOpenIdAndSessionKeyString(loginInfo.code, loginInfo.appid, loginInfo.secret); OpenIdAndSessionKey oiask = JsonConvert.DeserializeObject(res); if (!string.IsNullOrEmpty(oiask.errcode)) return null; return oiask; } /// /// 根据微信小程序平台提供的解密算法解密数据,推荐直接使用此方法 /// /// 登陆信息 /// 用户信息 public WechatUserInfo Decrypt(WechatLoginInfo loginInfo) { WechatUserInfo userInfo; if (loginInfo == null) return null; if (string.IsNullOrEmpty(loginInfo.code)) return null; OpenIdAndSessionKey oiask = DecodeOpenIdAndSessionKey(loginInfo); if (oiask == null) return null; if (!string.IsNullOrWhiteSpace(oiask.openid) && !string.IsNullOrWhiteSpace(loginInfo.rawData)) { userInfo = JsonConvert.DeserializeObject(loginInfo.rawData); userInfo.openId = oiask.openid; userInfo.unionId = oiask.unionId; return userInfo; } //if (!VaildateUserInfo(loginInfo, oiask)) // return null; userInfo = Decrypt(loginInfo.encryptedData, loginInfo.iv, oiask.session_key); userInfo.openId = oiask.openid; return userInfo; } /// /// 根据微信小程序平台提供的解密算法解密数据 /// /// 加密数据 /// 初始向量 /// 从服务端获取的SessionKey /// public WechatUserInfo Decrypt(string encryptedData, string iv, string sessionKey) { WechatUserInfo userInfo; //创建解密器生成工具实例 AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); //设置解密器参数 aes.Mode = CipherMode.CBC; aes.BlockSize = 128; aes.Padding = PaddingMode.PKCS7; //格式化待处理字符串 byte[] byte_encryptedData = Convert.FromBase64String(encryptedData); byte[] byte_iv = Convert.FromBase64String(iv); byte[] byte_sessionKey = Convert.FromBase64String(sessionKey); aes.IV = byte_iv; aes.Key = byte_sessionKey; //根据设置好的数据生成解密器实例 ICryptoTransform transform = aes.CreateDecryptor(aes.Key, aes.IV); byte[] xBuff = null; using (var ms = new MemoryStream()) { using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write)) { // cs.Read(decryptBytes, 0, decryptBytes.Length); // cs.Close(); // ms.Close(); byte[] xXml = Convert.FromBase64String(encryptedData); byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32]; Array.Copy(xXml, msg, xXml.Length); cs.Write(xXml, 0, xXml.Length); } xBuff = decode2(ms.ToArray()); } //解密 //byte[] final = transform.TransformFinalBlock(byte_encryptedData, 0, byte_encryptedData.Length); //生成结果 string result = Encoding.UTF8.GetString(xBuff); //反序列化结果,生成用户信息实例 userInfo = JsonConvert.DeserializeObject(result); return userInfo; } private static byte[] decode2(byte[] decrypted) { int pad = decrypted[decrypted.Length - 1]; if (pad < 1 || pad > 32) { pad = 0; } byte[] res = new byte[decrypted.Length - pad]; Array.Copy(decrypted, 0, res, 0, decrypted.Length - pad); return res; } } }