Home > Article > WeChat Applet > Introduction to WeChat Development (6) User Data Decryption
I often see some friends asking about the decryption process of mini program user data in the group, so I plan to write a tutorial on decrypting sensitive data of mini program users;
The encryption process is completed on the WeChat server, and the decryption process is in The applet and its own server are completed, that is, the following data is obtained from encryptData:
{ "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } }
Preparatory knowledge:
Base64 encoding and decoding
AES algorithm, padding mode, offset vector
The above 3 points are very important to understand the decryption process.
According to the official documents, I have sorted out the general decryption process, as follows:
The applet client calls wx.login, The callback contains js_code.
Then js_code is sent to server A (developer server). Server A initiates a request to the WeChat server with js_code, appId, secretkey and grant_type parameters in exchange for the user's openid and session_key ( session key).
After server A gets the session_key, it generates a random number we call 3rd_session, with 3rdSessionId as the key and session_key + openid as the valueCache to redis or memcached; because the WeChat team does not recommend transmitting the session_key directly on the network, the developer must generate a unique key to associate with the session_key. Its function is:
Return the 3rdSessionId to the client and maintain the applet login state.
Find the user session_key and openid through 3rdSessionId.
The client gets the 3rdSessionId and caches it in storage.
The user's sensitive data encryptedData can be obtained through wx.getUserIinfo.
The client sends encryptedData, 3rdSessionId and offset together to server A
Server A obtains session_key from the cache based on 3rdSessionId
Use AES to decrypt encryptedData on server A to achieve decryption of user sensitive data
Focus on the three links 6, 7, and 8.
AES decryption three parameters:
ciphertext encryptedData
key aesKey
Offset vector iv
Server-side decryption process:
The ciphertext and offset vector are sent from the client to the server. The two parameters perform the Base64_decodedecoding operation on the server side.
Get the session_key from the cache based on the 3rdSessionId, and Base64_decode the session_key to get aesKey, aes key.
Call the aes decryption method, the algorithm is AES-128-CBC, and the data is filled with PKCS#7.
The decryption process is explained below with an example of a mini program:
1. Log in with WeChat and obtain user information
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}) } })}})
2. Use code in exchange for 3rdSessionId
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) });
3. Initiate a decryption request
//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) });
4. Server-side decryption implementation (java)
/** * 解密用户敏感数据 * @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); }
5. AES decryption core code
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(); }
The final effect is as follows :
If your mini program is not bound to the WeChat open platform, the decrypted data does not contain the unionid parameter
The mini program is bound to the WeChat open platform connection
From the decrypted data, the only sensitive data is appid; I personally feel that openid is not sensitive data. Each user will generate a safe openid for each official account; openid Only available under the scope of appid. Unless your appid is also leaked.
So the appid can be obtained from the decrypted data. What is the purpose of the WeChat applet team? As I said before, openid is nothing without appid. Together, openid and appid are used to facilitate mini program developers to distinguish and isolate users between different mini program applications, and at the same time, they can combine the WeChat user system with the third-party business system. .
So I think the main use of sensitive data decryption is not to decrypt and send it back to the client, but to integrate WeChat user information into its own business on the server side.
【Related recommendations】
1. WeChat public account platform source code download
3. WeChat LaLa Takeaway 2.2.4 Decrypted Open Source Version of WeChat Rubik’s Cube Source Code
The above is the detailed content of Introduction to WeChat Development (6) User Data Decryption. For more information, please follow other related articles on the PHP Chinese website!