## **數據簽名**
為了保證數據傳輸過程中的數據真實性和完整性,我們需要對數據進行數字簽名,在接收簽名數據之后進 行簽名校驗。
數字簽名有兩個步驟,先按一定規則拼接要簽名的原始串,再選擇具體的算法和密鑰計算出簽名結果。 一般失敗的結果不簽名。
* * * * *
### 簽名原始串
無論是請求還是應答,簽名原始串按以下方式組裝成字符串:
1、data 字段內,所有參數按照字段名的 ascii 碼從小到大排序后使用 QueryString 的格式(即 key1=value1&key2=value2...)拼接而成,空值不傳遞,不參與簽名組串。
2、簽名原始串中,字段名和字段值都采用原始值,不進行 URL Encode。
3、返回的應答或通知消息可能會由于升級增加參數,請驗證應答簽名時注意允許這種情況。
* * * * *
### 簽名算法
目前暫只支持 MD5 簽名
MD5 簽名
MD5 是一種摘要生成算法,通過在簽名原始串后加上平臺通信密鑰的內容,進行 MD5 運算,形成的摘要字
符串即為簽名結果。為了方便比較,簽名結果統一轉換為大寫字符。
注意:簽名時將字符串轉化成字節流時指定的編碼字符集應與參數 charset 一致。
MD5 簽名計算公式:
sign = Md5(data數據原字符串&key=平臺密鑰). toUpperCase
toUpperCase 即MD5大寫
PHP寫法: strtoupper(Md5(data數據原字符串&key=平臺密鑰));
如:
假設以下為傳入參數:
~~~
array(4) {
["appid"] => string(10) "1308791035"
["method"] => string(7) "wx_scan"
["data"] => array(3) {
["total"] => int(100)
["store_id"] => string(2) "11"
["nonce_str"] => string(13) "5ad1d0db143a2"
}
["sign"] => string(32) "1802BF462E9DCD422BCF42D181068655"
}
~~~
>[danger] **簽名字段只針對Data字段數據**
如上data參數為
~~~
array(3) {
["total"] => int(100)
["store_id"] => string(2) "11"
["nonce_str"] => string(13) "5ad1d0db143a2"
}
~~~
假設平臺通信密鑰為:FFXHIXPOM6KV7OKOOEKV9L
1: 經過 a 過程 URL 鍵值對字典序排序后的字符串 string1 為:
~~~
nonce_str=5ad1d0db143a2&store_id=11&total=100
~~~
2: 經過 b 過程后得到 sign 為:
~~~
格式轉變為:
sign=strtoupper(md5(string1&key=FFXHIXPOM6KV7OKOOEKV9L))
格式轉變為:
sign=strtoupper(md5(nonce_str=5ad1d0db143a2&store_id=11&total=100&key=FFXHIXPOM6KV7OKOOEKV9L))
格式轉變為:
sign=1802BF462E9DCD422BCF42D181068655
~~~
最終簽名即為:
> 1802BF462E9DCD422BCF42D181068655