그룹 내에서 미니 프로그램 사용자 데이터의 복호화 프로세스에 대해 묻는 친구들을 자주 볼 수 있기 때문에 미니 프로그램 사용자의 민감한 데이터를 복호화하는 방법에 대한 튜토리얼을 작성할 예정입니다.
암호화 프로세스는 다음에서 완료됩니다. WeChat 서버 및 암호 해독 프로세스는 다음과 같습니다. 애플릿과 자체 서버가 완료되었습니다. 즉, encryptData에서 다음 데이터를 얻습니다.
{ "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } }
준비 지식:
위의 3가지 사항은 복호화 과정을 이해하는 데 매우 중요합니다.
공문서에 따르면 일반적인 복호화 과정을 다음과 같이 정리했습니다.
애플릿 클라이언트가 wx를 호출합니다. 로그인, 콜백에는 js_code가 포함되어 있습니다.
그런 다음 js_code를 서버 A(개발자 서버)로 보내고, 서버 A는 사용자의 openid 및 session_key와 교환하여 js_code, appId, secretkey 및 grant_type 매개변수를 사용하여 WeChat 서버에 요청을 시작합니다( 세션 키).
서버 A는 session_key를 얻은 후 3rdSessionId를 키로, session_key + openid를 값으로 사용하여 3rd_session이라는 임의의 숫자를 생성합니다. 캐시 를 redis 또는 memcached; WeChat 팀은 session_key를 네트워크에서 직접 전송하는 것을 권장하지 않으므로 개발자는 session_key와 연결할 고유 키를 생성해야 합니다. 기능은
3rdSessionId를 클라이언트에 반환하고 미니 프로그램 로그인 상태를 유지합니다.
3rdSessionId를 통해 사용자 session_key와 openid를 찾습니다.
클라이언트가 3rdSessionId를 얻은 후 스토리지에 캐시됩니다.
사용자의 민감한 데이터는 암호화되어 데이터를 얻을 수 있습니다. getUserIinfo. <… 🎜 >
AES 암호 해독 세 가지 매개변수:
암호화된 텍스트
key aesKey
디코딩
작업.aes 복호화 방법을 호출하면 알고리즘은 AES-128-CBC이고 데이터는 PKCS#7로 채워집니다.
var that = this;wx.login({success: function (res) { //微信js_code that.setData({wxcode: res.code}); //获取用户信息 wx.getUserInfo({ success: function (res) { //获取用户敏感数据密文和偏移向量 that.setData({encryptedData: res.encryptedData}) that.setData({iv: res.iv}) } })}})
var httpclient = require('../../utils/httpclient.js') VAR that = this//httpclient.req(url, data, method, success, fail)httpclient.req( 'http://localhost:8090/wxappservice/api/v1/wx/getSession', { apiName: 'WX_CODE', code: this.data.wxcode }, 'GET', function(result){ var thirdSessionId = result.data.data.sessionId; that.setData({thirdSessionId: thirdSessionId}) //将thirdSessionId放入小程序缓存 wx.setStorageSync('thirdSessionId', thirdSessionId) }, function(result){ console.log(result) });
//httpclient.req(url, data, method, success, fail)httpclient.req('http://localhost:8090/wxappservice/api/v1/wx/decodeUserInfo', { apiName: 'WX_DECODE_USERINFO', encryptedData: this.data.encryptedData, iv: this.data.iv, sessionId: wx.getStorageSync('thirdSessionId') }, 'GET', function(result){ //解密后的数据 console.log(result.data) }, function(result){ console.log(result) });
/** * 解密用户敏感数据 * @param encryptedData 明文 * @param iv 加密算法的初始向量 * @param sessionId 会话ID * @return */@Api(name = ApiConstant.WX_DECODE_USERINFO)@RequestMapping(value = "/api/v1/wx/decodeUserInfo", method = RequestMethod.GET, produces = "application/json")public Map<String,Object> decodeUserInfo(@RequestParam(required = true,value = "encryptedData")String encryptedData, @RequestParam(required = true,value = "iv")String iv, @RequestParam(required = true,value = "sessionId")String sessionId){ //从缓存中获取session_key Object wxSessionObj = redisUtil.get(sessionId); if(null == wxSessionObj){ return rtnParam(40008, null); } String wxSessionStr = (String)wxSessionObj; String sessionKey = wxSessionStr.split("#")[0]; try { AES aes = new AES(); byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv)); if(null != resultByte && resultByte.length > 0){ String userInfo = new String(resultByte, "UTF-8"); return rtnParam(0, userInfo); } } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return rtnParam(50021, null); }
public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException { initialize(); try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); Key sKeySpec = new SecretKeySpec(keyByte, "AES"); cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化 byte[] result = cipher.doFinal(content); return result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
최종 효과는 다음과 같습니다.
귀하의 미니 프로그램이 WeChat 오픈 플랫폼에 바인딩되지 않은 경우 해독된 데이터에는 Unionid 매개변수가 포함되지 않습니다
미니 프로그램은 WeChat 개방형 플랫폼 연결에 바인딩되어 있습니다 요약복호화된 데이터 중 유일한 민감한 데이터는 appid입니다. 저는 개인적으로 openid가 민감한 데이터가 아니라고 생각합니다. 🎜>safe 각 공식 계정의 openid는 appid 범위에서만 사용 가능합니다. 귀하의 앱도 유출되지 않는 한.
그러면 복호화된 데이터에서 appid를 얻을 수 있는 거죠. WeChat Mini 프로그램 팀의 목적은 무엇인가요? 앞서 말했듯이, openid는 appid 없이는 아무것도 아닙니다. openid와 appid를 함께 사용하면 미니 프로그램 개발자가 서로 다른 미니 프로그램 애플리케이션 간에 사용자를 구별하고 격리할 수 있으며 동시에 WeChat 사용자 시스템을 세 번째 시스템과 결합할 수 있습니다. -파티 비즈니스 시스템.
그래서 민감한 데이터 복호화의 주요 용도는 복호화하여 클라이언트에게 다시 보내는 것이 아니라 서버 측에서 WeChat 사용자 정보를 자체 비즈니스에 통합하는 것이라고 생각합니다.
3.
WeChat Lala Takeaway 2.2.4는 WeChat Rubik's Cube 소스 코드의 오픈 소스 버전을 해독합니다위 내용은 WeChat 개발 소개 (6) 사용자 데이터 복호화의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!