欧美日韩国产一区,亚洲一区视频,色综合久久久久,私密按摩师舌头伸进去了,99re6这里只有精品,夜夜性日日交xxx性hd

精華

小程序基礎篇之數據解密

  • • 發表于 8年前
  • • 作者 JeremyLu
  • • 15732 人瀏覽
  • • 37 條評論
  • • 最后編輯時間 8年前
  • • 來自 [技 術]

原創聲明:本文為作者原創,未經允許不得轉載,經授權轉載需注明作者和出處

經常看到有點的小伙伴在群里問小程序用戶數據解密流程,所以打算寫一篇關于小程序用戶敏感數據解密教程;

加密過程微信服務器完成,解密過程在小程序和自身服務器完成,即由 encryptData 得到如下數據:

{
    "openId": "OPENID",
    "nickName": "NICKNAME",
    "gender": GENDER,
    "city": "CITY",
    "province": "PROVINCE",
    "country": "COUNTRY",
    "avatarUrl": "AVATARURL",
    "unionId": "UNIONID",
    "watermark":
    {
        "appid":"APPID",
        "timestamp":TIMESTAMP
    }
}

準備知識:

  1. Base64編解碼
  2. AES算法、填充模式、偏移向量
  3. session_key會話密鑰,以及怎么存儲和獲取

以上3點對于理解解密流程非常重要

根據官方文檔,我梳理了大致的解密流程,如下:

  1. 小程序客戶端調用wx.login,回調里面包含js_code。
  2. 然后將js_code發送到服務器A(開發者服務器),服務器A向微信服務器發起請求附帶js_code、appId、secretkey和grant_type參數,以換取用戶的openid和session_key(會話密鑰)。
  3. 服務器A拿到session_key后,生成一個隨機數我們叫3rd_session,以3rdSessionId為key,以session_key + openid為value緩存到redis或memcached中;因為微信團隊不建議直接將session_key在網絡上傳輸,由開發者自行生成唯一鍵與session_key關聯。其作用是:
    1. 將3rdSessionId返回給客戶端,維護小程序登錄態。
    2. 通過3rdSessionId找到用戶session_key和openid。
  4. 客戶端拿到3rdSessionId后緩存到storage,
  5. 通過wx.getUserIinfo可以獲取到用戶敏感數據encryptedData 。
  6. 客戶端將encryptedData、3rdSessionId和偏移量一起發送到服務器A
  7. 服務器A根據3rdSessionId從緩存中獲取session_key
  8. 在服務器A使用AES解密encryptedData,從而實現用戶敏感數據解密

重點在6、7、8三個環節。
AES解密三個參數:

  • 密文 encryptedData
  • 密鑰 aesKey
  • 偏移向量 iv

服務端解密流程:

  1. 密文和偏移向量由客戶端發送給服務端,對這兩個參數在服務端進行Base64_decode解編碼操作。
  2. 根據3rdSessionId從緩存中獲取session_key,對session_key進行Base64_decode可以得到aesKey,aes密鑰。
  3. 調用aes解密方法,算法為 AES-128-CBC,數據采用PKCS#7填充。

下面結合小程序實例說明解密流程:

  1. 微信登錄,獲取用戶信息
    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. 使用code換取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. 發起解密請求
    //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. 服務端解密實現(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解密核心代碼

    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();
         }
    

最后的效果如下:

解密數據有一個與官方文檔不一致的地方是實際解密得到的數據不包含unionId。

總結

從解密的數據看,算得上敏感的數據只有appid;個人覺得openid不是敏感數據,每個用戶針對每個公眾號會產生一個安全的openid;openid只有在appid的作用域下可用。除非你的appid也泄露了。

那么可以從解密數據得到appid,微信小程序團隊是何用意呢?還是前面那句話,openid脫離了appid就什么都不是,openid和appid一起為了方便小程序開發者做到不同小程序應用之間用戶區分和隔離,同時能夠將微信用戶體系與第三方業務體系結合。

所以我認為敏感數據解密的主要用處不是解密后回傳給客戶端,而是在服務端將微信用戶信息融入到自身業務當中。

詳細學習請參考:
小程序數據解密:https://github.com/cocoli/weixin_smallexe/tree/master/chaptor_05
java解密實現:https://github.com/cocoli/springboot-weapp-demo
相關討論專題:http://www.mkhyf.com/topic/429

分享到:
37條評論
Ctrl+Enter
作者

JeremyLu

JeremyLu

APP:1 帖子:19 回復:189 積分:627

已加入社區[3072]天

我就是我不一樣的煙火

作者詳情》
Top