赞
踩
最近做一个微信小程序需用到微信运动数据,根据文档,我写了一个demo;先总结一下步骤,流程简单如下:
1、调用小程序API:wx.login获取code和sessionKey;
2、调用小程序API: wx.getWeRunData获取微信运动数据(加密的);
3、解密步骤2的数据;
我后台用C#的,其实其他语言原理一样,只有解密数据一个核心方法;
加密数据解密算法
接口如果涉及敏感数据(如wx.getUserInfo
当中的 openId 和unionId ),接口的明文内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptedData )进行对称解密。 解密算法如下:
微信官方提供了多种编程语言的示例代码(点击下载)。每种语言类型的接口名字均一致。调用方式可以参照示例。
下载示例代码,没有C#的,只有C++、nodejs、python、php的,顿时受到巨大的打击。在网上找C#的AES-128-CBC算法,就没有一个好用的,下载下来半天调不通,看看nodejs和python的代码,简单到令人发指,顿时让我的信心再次遭受打击。
必须先登录获取到session_key 然后再去获取加密的步数,如果先获取步数再去登陆用登录的session_key去解密会报“填充无效,无法被移除。” ,我在调试过程中就碰到这个问题我在后端登录前端给我加密数据解密就出问题了
api
- [Route("api/[controller]/[action]")]
- [ApiController]
- public class WeChatController : TestControllerBase
- {
-
- private readonly ICacheManager _cacheManager;
- private IHttpClientFactory _httpClient;
- public WeChatController( ICacheManager cacheManager,IHttpClientFactory httpClient)
- {
- this._cacheManager = cacheManager;
- this._httpClient=httpClient;
- }
-
- /// <summary>
- /// 获取微信ID
- /// </summary>
- /// <returns></returns>
- [HttpGet]
- public async Task<dynamic> GetWechatID(string js_code)
- {
-
- try
- {
- using (var client = _httpClient.CreateClient())
- {
- var url = $"https://api.weixin.qq.com/sns/jscode2session?appid=这里是appid&secret=这里是secret&js_code={js_code}&grant_type=authorization_code";
- //使用注入的httpclientfactory获取client
-
- client.BaseAddress = new Uri(url);
- //设置请求体中的内容,并以post的方式请求
- var response = await client.GetAsync(url);
- //获取请求到数据,并转化为字符串
- var result = response.Content.ReadAsStringAsync().Result;
- dynamic aa = JsonConvert.DeserializeObject<dynamic>(result);
- string session_key = aa.session_key;
-
- string openid = aa.openid;
- string bb = PublicMethods.Encrypt(openid);
- _cacheManager.GetCache("微信登录").Remove(bb);
- _cacheManager.GetCache("微信登录").Set(bb, session_key);我将sessionkey缓存起来解密时需要用
- return Json(new { ok = true, msg = "sucess", data = bb });
- }
-
- }
- catch (Exception e)
- {
- return Json(new { ok = false, msg = "error", data = e.Message });
- }
- }
-
- /// <summary>
- /// 解密
- /// </summary>
- /// <param encryptedData="需要解密的步数"></param>
- /// <param iv="不知道"></param>
- /// <param wechatid="登录时缓存的session_key"></param>
- /// <returns></returns>
- [HttpPost]
- public ActionResult Decrypt(T微信步数解密 Decrypt)
- {
- string sessionKey = _cacheManager.GetCache("微信登录").GetOrDefault(Decrypt.wechatid).ToString(); //取出OnLogin的sessionKey
- string rawData =PublicMethods.AES_decrypt(Decrypt.encryptedData, sessionKey, Decrypt.iv);
- if (string.IsNullOrEmpty(rawData) == false)
- {
- return Ok(rawData);
- }
- return BadRequest("解密失败");
- }
- /// <summary>
- /// AES解密
- /// </summary>
- /// <param name="encryptedDataStr"></param>
- /// <param name="key"></param>
- /// <param name="iv"></param>
- /// <returns></returns>
- private static string AES_decrypt(string encryptedDataStr, string key, string iv)
- {
- try
- {
-
- RijndaelManaged rijalg = new RijndaelManaged();
- //-----------------
- //设置 cipher 格式 AES-128-CBC
-
- rijalg.KeySize = 128;
-
- rijalg.Padding = PaddingMode.PKCS7;
- rijalg.Mode = CipherMode.CBC;
-
- rijalg.Key = Convert.FromBase64String(key);
- rijalg.IV = Convert.FromBase64String(iv);
-
-
- byte[] encryptedData = Convert.FromBase64String(encryptedDataStr);
- //解密
- ICryptoTransform decryptor = rijalg.CreateDecryptor(rijalg.Key, rijalg.IV);
-
- string result = null;
-
- using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
- {
- using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
- {
- using (StreamReader srDecrypt = new StreamReader(csDecrypt))
- {
-
- result = srDecrypt.ReadToEnd();
- }
- }
- }
- return result;
- }
- catch (Exception e)
- {
-
- return e.Message;
- }
-
-
- }
- private class T微信步数解密
- {
- public string iv { get; set; }
- public string encryptedData { get; set; }
- public string wechatid { get; set; }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。