侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

.NET微信小程序用户数据的签名验证和解密代码

微信(小程序)  /  管理员 发布于 3年前   220

微信小程序时下大热,抱着学习的心态了解了一下,目前没有搜到完整的.NET用户数据签名验证和解密代码,于是就写了一点。

简单使用方法:

1、客户端调用wx.getUserInfo方法,服务端创建WeChatLoginInfo类的实例接收客户端发来的数据;
2、服务端新建WeChatAppDecrypt类的实例,初始化此类时需传入appId与AppSecret用于验证;
3、调用WeChatAppDecrypt类中的Decrypt方法,传入步骤1中获取的WechatLoginInfo实例;
4、得到WechatUserInfo类的实例,其中就是解密好的数据。

话不多说,注释比较详尽,感兴趣的朋友可以参考。

using System;using System.Net;using System.Net.Http;using System.Net.Http.Headers;using Newtonsoft.Json;using System.Security.Cryptography;using System.Text; namespace BroadSky.WeChatAppDecrypt{  /// <summary>  /// 处理微信小程序用户数据的签名验证和解密  /// </summary>  public class WeChatAppDecrypt  {    private string appId;    private string appSecret;     /// <summary>    /// 构造函数    /// </summary>    /// <param name="appId">应用程序的AppId</param>    /// <param name="appSecret">应用程序的AppSecret</param>    public WeChatAppDecrypt(string appId, string appSecret)    {      this.appId = appId;      this.appSecret = appSecret;      return;    }     /// <summary>    /// 获取OpenId和SessionKey的Json数据包    /// </summary>    /// <param name="code">客户端发来的code</param>    /// <returns>Json数据包</returns>    private string GetOpenIdAndSessionKeyString(string code)    {      string temp = "https://api.weixin.qq.com/sns/jscode2session?" +         "appid=" + appId        + "&secret=" + appSecret        + "&js_code=" + code         + "&grant_type=authorization_code";       return GetResponse(temp);     }     /// <summary>    /// 反序列化包含OpenId和SessionKey的Json数据包    /// </summary>    /// <param name="code">Json数据包</param>    /// <returns>包含OpenId和SessionKey的类</returns>    public OpenIdAndSessionKey DecodeOpenIdAndSessionKey(WechatLoginInfo loginInfo)    {      OpenIdAndSessionKey oiask = JsonConvert.DeserializeObject<OpenIdAndSessionKey>(GetOpenIdAndSessionKeyString(loginInfo.code));      if (!String.IsNullOrEmpty(oiask.errcode))        return null;      return oiask;    }     /// <summary>    /// 根据微信小程序平台提供的签名验证算法验证用户发来的数据是否有效    /// </summary>    /// <param name="rawData">公开的用户资料</param>    /// <param name="signature">公开资料携带的签名信息</param>    /// <param name="sessionKey">从服务端获取的SessionKey</param>    /// <returns>True:资料有效,False:资料无效</returns>    public bool VaildateUserInfo(string rawData, string signature, string sessionKey)    {      //创建SHA1签名类      SHA1 sha1 = new SHA1CryptoServiceProvider();      //编码用于SHA1验证的源数据      byte[] source = Encoding.UTF8.GetBytes(rawData + sessionKey);      //生成签名      byte[] target = sha1.ComputeHash(source);      //转化为string类型,注意此处转化后是中间带短横杠的大写字母,需要剔除横杠转小写字母      string result = BitConverter.ToString(target).Replace("-","").ToLower();      //比对,输出验证结果      return signature == result;    }     /// <summary>    /// 根据微信小程序平台提供的签名验证算法验证用户发来的数据是否有效    /// </summary>    /// <param name="loginInfo">登陆信息</param>    /// <param name="sessionKey">从服务端获取的SessionKey</param>    /// <returns>True:资料有效,False:资料无效</returns>    public bool VaildateUserInfo(WechatLoginInfo loginInfo, string sessionKey)    {      return VaildateUserInfo(loginInfo.rawData, loginInfo.signature, sessionKey);    }     /// <summary>    /// 根据微信小程序平台提供的签名验证算法验证用户发来的数据是否有效    /// </summary>    /// <param name="loginInfo">登陆信息</param>    /// <param name="idAndKey">包含OpenId和SessionKey的类</param>    /// <returns>True:资料有效,False:资料无效</returns>    public bool VaildateUserInfo(WechatLoginInfo loginInfo, OpenIdAndSessionKey idAndKey)    {      return VaildateUserInfo(loginInfo, idAndKey.session_key);    }     /// <summary>    /// 根据微信小程序平台提供的解密算法解密数据    /// </summary>    /// <param name="encryptedData">加密数据</param>    /// <param name="iv">初始向量</param>    /// <param name="sessionKey">从服务端获取的SessionKey</param>    /// <returns></returns>    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();            //解密      byte [] final = transform.TransformFinalBlock(byte_encryptedData, 0, byte_encryptedData.Length);       //生成结果      string result = Encoding.UTF8.GetString(final);       //反序列化结果,生成用户信息实例      userInfo = JsonConvert.DeserializeObject<WechatUserInfo>(result);       return userInfo;     }     /// <summary>    /// 根据微信小程序平台提供的解密算法解密数据,推荐直接使用此方法    /// </summary>    /// <param name="loginInfo">登陆信息</param>    /// <returns>用户信息</returns>    public WechatUserInfo Decrypt(WechatLoginInfo loginInfo)    {      if (loginInfo == null)        return null;       if (String.IsNullOrEmpty(loginInfo.code))        return null;       OpenIdAndSessionKey oiask = DecodeOpenIdAndSessionKey(loginInfo);       if (oiask == null)        return null;       if (!VaildateUserInfo(loginInfo, oiask))        return null;       WechatUserInfo userInfo = Decrypt(loginInfo.encryptedData, loginInfo.iv, oiask.session_key);       return userInfo;    }     /// <summary>    /// GET请求    /// </summary>    /// <param name="url"></param>    /// <returns></returns>    private string GetResponse(string url)    {      if (url.StartsWith("https"))        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;       HttpClient httpClient = new HttpClient();      httpClient.DefaultRequestHeaders.Accept.Add(      new MediaTypeWithQualityHeaderValue("application/json"));      HttpResponseMessage response = httpClient.GetAsync(url).Result;       if (response.IsSuccessStatusCode)      {        string result = response.Content.ReadAsStringAsync().Result;        return result;      }      return null;    }       }  /// <summary>  /// 微信小程序登录信息结构  /// </summary>  public class WechatLoginInfo  {    public string code { get; set; }    public string encryptedData { get; set; }    public string iv { get; set; }    public string rawData { get; set; }    public string signature { get; set; }  }  /// <summary>  /// 微信小程序用户信息结构  /// </summary>  public class WechatUserInfo  {    public string openId { get; set; }    public string nickName { get; set; }    public string gender { get; set; }    public string city { get; set; }    public string province { get; set; }    public string country { get; set; }    public string avatarUrl { get; set; }    public string unionId { get; set; }    public Watermark watermark { get; set; }     public class Watermark    {      public string appid { get; set; }      public string timestamp { get; set; }    }  }  /// <summary>  /// 微信小程序从服务端获取的OpenId和SessionKey信息结构  /// </summary>  public class OpenIdAndSessionKey  {    public string openid { get; set; }    public string session_key { get; set; }    public string errcode { get; set; }    public string errmsg { get; set; }  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    .Net之微信小程序获取用户UnionID的实现
    下一条:
    微信小程序基于腾讯云对象存储的图片上传功能
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 小程序开发之跳转微信直播示例api(0个评论)
    • 在uni_app中开发小程序之常用功能示例代码汇总(0个评论)
    • 小程序开发之多端框架:taro(0个评论)
    • 微信小程序前端使用七牛云官方SDK上传七牛云代码示例(0个评论)
    • 百度小程序审核未通过,真机审核存在点击返回键退出小程序...解决方式之一tabBar(0个评论)
    • 近期文章
    • 如何优雅处理async await错误推荐:await-to-js库(0个评论)
    • lodash工具库(0个评论)
    • 在Laravel项目中使用中间件方式统计用户在线时长功能代码示例(0个评论)
    • 在Laravel中构建业务流程模型(0个评论)
    • windows系统中安装FFMpeg及在phpstudy环境php7.3 + php-ffmpeg扩展的使用流程步骤(0个评论)
    • 在go语言中对浮点的数组、切片(slice)进行正向排序和反向排序(0个评论)
    • 在go语言中对整数数组、切片(slice)进行排序和反向排序(0个评论)
    • 在go语言中对字符串数组、切片(slice)进行排序和反向排序(0个评论)
    • 最新国内免注册ChatGPT体验站_ChatGPT镜像站访问链接地址2023/3/28持续更新(0个评论)
    • 在Laravel项目中的实现无密码认证之:发送邮箱链接授权(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客