老司机三级_天天干天天操天天爽_女人被爽到娇喘呻吟视频_久久国产精品99久久久大便 - 亚洲日本系列

7:用戶數據簽名詳解(加解密、簽名系列)

  • • 發表于 9年前
  • • 作者 Roluce
  • • 7866 人瀏覽
  • • 2 條評論
  • • 最后編輯時間 9年前
  • • 來自 [技 術]

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

1:為什么要做簽名


由上圖可知:有三個傳輸過程:

1:微信服務器A與小程序B之間的數據傳輸
2:小程序B與自己服務器C之間的數據傳輸
3:微信服務器A與自己服務器C之間的數據傳輸


破壞數據完整性的原因:

正常來說,數據從A傳輸到B,再到C,ABC三點的數據都是一樣的。
但也許是不一致的,比如:
1:http傳輸過程中因為軟件或硬件問題造成數據丟失一部分。
2:黑客攔截數據、修改數據、繼續發送數據。
3:等等等


數據簽名的原因:

如果不做任何措施,從B發出數據data,傳輸過程中“丟失部分數據”或”被黑客修改數據”,然后C接收到數據data2

在C不知道接收的數據data2是否和B發出的數據data是否一致,
如果把不一致的數據當做正確的數據繼續操作,將會出現各種安全性的問題。

為了讓C知道:接收的數據是否和B發出的數據是否一致,所以采取了簽名的機制。


數據完整、安全的重要性:
比如:你去銀行取錢,營業員從“遠程服務器”查詢你的“賬戶余額”。
“遠程服務器”發送過來1000元,你讓“同伙”劫持數據,把這1000元改成5000元,并發送給營業員。如果此時沒有做數據完整性校驗,營業員收到你的余額就是5000元,他就給你5000元。本來你余額為1000元,結果給你5000元。
這僅僅是一個例子,在不同的應用場合,如果不做數據完整性校驗,會出現各種問題。
所以,數據的安全、完整性很重要,所以敏感的數據必須做簽名驗證。


2:有簽名的數據傳輸與判定

現以上圖中BC之間傳輸為例,說明具體數據傳輸過程:

一:BC先約定好三點:
1:“簽名算法”
2:“密鑰”(一般是隨機生成復雜的字符串)
3:“算法參數的組裝規則”(簡稱’參規’)

(為了防止密鑰的泄露,此密鑰僅用于本地,不能在網絡傳輸,以防劫持)

二:在B執行:簽名算法( 參規(原始數據,密鑰) )=簽名
三:從B發出“原始數據”和“簽名”到C
四:網絡傳輸過程(安全的或者數據丟失或者黑客劫持)
五:C接收到“待定數據”和“簽名”
六:在C執行:簽名算法( 參規(待定數據,密鑰) )=新簽名

判定:
1:如果接收的簽名=新簽名,就說明數據完整、安全(待定數據=原始數據)
2:如果接收的簽名!=新簽名,說明待定數據異常、不安全(待定數據!=原始數據)


由上邊可知:小程序和開發者的三點約定為:
1:簽名算法為:sha1
2:密鑰為:session_key
3:算法參數的組裝規則:“原始數據字符串”連接“密鑰字符串”
(注:小程序用的規則如上,比較簡單。還可以隨意約定規則,比如:數據+密鑰+*#abc等)

所以小程序生成簽名的公式:
sha1(原始數據+session_key)=signutrue
注:官方文檔中的rawData指的就是“原始數據”,raw英文為“原始的,未被加工的意思”


數據從B發送到C的全部情況(四種):

1:傳輸過程中,一切正常。

在B:簽名算法(數據+密鑰)=簽名,發出“數據”、”簽名”
傳輸過程:”數據”沒變,“簽名”沒變
在C:簽名算法(數據+密鑰)=簽名
結果:簽名==簽名,可以判定數據安全

2:傳輸過程中,黑客修改了“數據”

在B:簽名算法(數據+密鑰)=簽名,發出“數據”、”簽名”
傳輸過程:黑客修改了”數據”變為”數據2”,“簽名”沒變
在C:簽名算法(數據2+密鑰)=簽名2
結果:簽名!=簽名2,可以判定數據不安全

3:傳輸過程中,黑客修改了“密鑰”

在B:簽名算法(數據+密鑰)=簽名,發出“數據”、”簽名”
傳輸過程:黑客修改了”簽名”變為”簽名2”,“數據”沒變
在C:簽名算法(數據+密鑰)=簽名
結果:簽名2!=簽名,可以判定數據不安全

4:傳輸過程中,黑客修改了“數據和密鑰”

在B:簽名算法(數據+密鑰)=簽名,發出“數據”、”簽名”
傳輸過程:黑客修改了”數據和簽名”變為”數據2和簽名2”
在C:簽名算法(數據2+密鑰)=簽名3
結果:簽名2和簽名3有幾率相等,什么情況下相等呢?

因為在C,簽名算法(數據2+密鑰)=簽名3
只有黑客獲取密鑰,在傳輸過程中也執行,簽名算法(數據2+密鑰)=簽名2
簽名2才等于簽名3。
因為為了防止密鑰的泄露,此密鑰僅用于本地,不在網絡傳輸,所以黑客無法獲取密鑰。
結果:簽名2!=簽名3,可以判定數據不安全。


3:signature簽名僅檢驗”基本信息”的完整性


B1的簽名相關數據為:
1:rawData
2:signature


通過console.log()打印的rawData的數據為:

"{"nickName":"三石","gender":1,"language":"en","city":"Liaocheng","province":"Shandong","country":"CN", "avatarUrl":"http://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJX1ic14jrA6pbgCw2r8PxlmOtAr5zlvE4icfvwRvelsFAya13PscYatzERE29wia7A1R53fy3QwJxgg/0"}"

結論1:(由rawData的數據信息)

rawData的數據僅包含基本信息的數據,userInfo內的信息永遠是保持一致的。
只是格式不一樣,一個是JSON字符串,一個是對象。

結論2:(由rawData的數據信息)

在微信服務器簽名signature的生成過程為:
signature=sha1(rawData,session_key)
所以signature只能保證基本信息的數據完整性和安全性。

結論3:(由rawData的數據信息)

**encryptedData與iv也需要單獨的檢驗數據完整性
具體方法見此文:
8:用戶敏感信息完整性檢驗(加解密、簽名系列)


4:“用戶基本信息”的數據簽名校驗

通常是在自己服務器后臺做驗證通常是在自己服務器后臺做驗證

微信服務器端的響應:

小程序調用wx.getUserInfo()時,微信服務器
通過原始數據,session_key生成簽名發送給小程序。
即:sha1( 原始數據+ session_key )=signature


開發者的操作為:

1:先獲取session_key(傳送門)
2:把小程序端調用wx.getUserInfo()獲取數據中的 rawData(原始數據)、signature,用wx.request()發送到自己的服務器。
3:在服務器后臺,接收傳送來的rawData(原始數據)、signature。使用相同的算法計算出簽名signature2
即:sha1( rawData+ session_key )=signature2
結果:
比對 signature 與 signature2 即可校驗數據的完整性。


算法參數的組裝規則的例子:

由官方文檔知道:
sha1( rawData+ session_key )=signature
即sha1的參數為:rawData字符串“連接”sesson_key字符串。

如wx.getUserInfo的數據校驗:
接口返回的rawData:

{ "nickName": "Band", "gender": 1, "language": "zh_CN", "city": "Guangzhou", "province": "Guangdong", "country": "CN", "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0" }


用戶的 session-key:
HyVFkGl5F5OQWJZZaNzBBg==
所以,用于簽名的字符串為:

{ "nickName": "Band", "gender": 1, "language": "zh_CN", "city": "Guangzhou", "province": "Guangdong", "country": "CN", "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0" }HyVFkGl5F5OQWJZZaNzBBg==

使用sha1得到的結果為:
75e81ceda165f4ffa64f4068af58c64b8f54b88c


5:全部代碼實現(PHP后臺版)

0:test.wxml(小程序)

 <button bindtap="tap">tap</button>

1:test.js(小程序)

Page({

  tap: function () {

    //調用登錄接口
    wx.login({
      success: function (login) {

        //成功,返回登錄憑證js_code
        var js_code = login.code;

        //調用獲取用戶信息接口
        wx.getUserInfo({
          success: function (res) {

            //獲取原始數據 
            var rawData = res.rawData;
            //獲取簽名
            var signature = res.signature;

            //調用網絡請求接口,把數據發送給服務器
            wx.request({
              url: 'http://www.yoururl.com/test.php',
              data: {
                js_code: js_code,       //js_code用戶獲取session_key
                rawdata: rawData,      //原始數據
                signature: signature,  //簽名
              },
              method: 'GET', //用Get的請求方式
              header: {
                'content-type': 'application/json'
              },
              success: function (data) {

                //成功,返回signature,signature2數據
                console.log(data);
              }
            })
          }
        })
      }
    });
  }

})

2:PHP后臺實現代碼

<?php

 /*1:獲取session_key********************************/

    //AppID(小程序ID)
    $APPID= "wx138cb91a9900af75"; 

    //AppSecret(小程序密鑰)
    $SECRET = "0d082ea09511df65ef3f2300fdbe0147"; 

    //接收小程序端發來的js_code
    $js_code = $_GET[js_code];

    //小程序接口(appid+secret+js_code=sessionId+openId)
    $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$APPID}&secret={$SECRET}&js_code={$js_code}&grant_type=authorization_code";


    //模擬網頁的GET請求
    $timeout = 5; 
    $ch = curl_init();                              //初始化curl   
    curl_setopt($ch, CURLOPT_URL, $url);            //設置訪問的url地址   
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);    //參數為1表示傳輸數據,為0表示直接輸出顯示。 
    curl_setopt($ch, CURLOPT_HEADER, 0);            //參數為0表示不帶頭文件,為1表示帶頭文件  

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);   //獲取https需要加上此
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);   //獲取https需要加上此

    $json_data = curl_exec($ch);   //執行命令并把獲取的數據賦值給$output
    curl_close($ch);            //關閉URL請求   


    //返回的Json數據轉換成php對象 
    $obj = json_decode($json_data);

    //獲得session_key
    $session_key =$obj->session_key;  

 /*2:校驗數據有效性********************************/

      //獲取小程序發送來的簽名signature
     $signature = $_GET['signature']; 

     //獲取小程序發送來的原始數據rawData
     $rawdata = $_GET['rawdata'];    

    //生成signature2
    $signature2 = sha1($rawdata.$session_key);

    //生成鍵值對數組,用于轉換為Json數組發送給小程序
    $arr = ["signature"=>$signature,"signature2"=>$signature2];

    //鍵值對數組轉換為json數組
    $arr_json = json_encode($arr);

    //發送給小程序,在wx.request()的sucess方法接收
    echo $arr_json;



?>
分享到:
2條評論
Ctrl+Enter
作者

Roluce

Roluce

APP:0 帖子:50 回復:112 積分:3610

已加入社區[3218]天

山東_聊城_qq:635068

作者詳情》
Top