4 數字簽名
為了保證數據傳輸過程中的數據真實性和完整性,我們需要對數據進行數字簽名,在接收簽名數據之後進行簽名校驗。
數字簽名有兩個步驟,先按一定規則拼接要簽名的原始串,再選擇具體的演算法和密鑰計算出簽名結果。
一般失敗的結果不簽名。
4.1 簽名原始串
無論是請求還是應答,簽名原始串按以下方式組裝成字串:
1、除sign字段外,所有參數按照字段名的ascii碼從小到大排序後使用QueryString的格式(即key1=value1&key2=value2…)拼接而成,空值不傳遞,不參與簽名組串。
2、簽名原始串中,字段名和字段值都採用原始值,不進行 URLEncode。
3、平臺返回的應答或通知消息可能會由於升級增加參數,請驗證應答簽名時注意允許這種情況。舉例: 調用某個接口,接口有如下字段:
<xml>
<body><![CDATA[測試支付]]></body>
<mch_create_ip><![CDATA[127.0.0.1]]></mch_create_ip>
<mch_id><![CDATA[7551000001]]></mch_id>
<nonce_str><![CDATA[1409196838]]></nonce_str>
<notify_url><![CDATA[http://227.0.0.1:9001/javak/]]></notify_url>
<out_trade_no><![CDATA[141903606228]]></out_trade_no>
<service><![CDATA[pay.weixin.jspay]]></service>
<sign><![CDATA[69DB852498AAE1498C04E20414021980]]></sign>
<total_fee><![CDATA[1]]></total_fee>
</xml>
正確的簽名字段排序為:
body=測試支付&mch_create_ip=127.0.0.1&mch_id=
7551000001&nonce_str=1409196838¬ify_url=http: //227.0.0.1:9001/javak/&out_trade_no
=141903606228&service=pay.weixin.jspay&total_fee=1
4.2 簽名演算法
目前暫只支持 MD5 簽名
MD5 是一種摘要生成演算法,通過在簽名原始串後加上商戶通信密鑰的內容,進行MD5運算,形成的摘要字串即為簽名結果。為了方便比較,簽名結果統一轉換為大寫字元。
注意:簽名時將字串轉化成位元組流時指定的編碼字元集應與參數 charset 一致。 MD5 簽名計算公式:
sign=Md5(原字串&key=商戶密鑰). toUpperCase
假設以下為 XML 傳入參數
<xml>
<body><![CDATA[測試支付]]></body>
<mch_create_ip><![CDATA[127.0.0.1]]></mch_create_ip>
<mch_id><![CDATA[7551000001]]></mch_id>
<nonce_str><![CDATA[1409196838]]></nonce_str>
<notify_url><![CDATA[http://227.0.0.1:9001/javak/]]></notify_url>
<out_trade_no><![CDATA[141903606228]]></out_trade_no>
<service><![CDATA[pay.weixin.jspay]]></service>
<sign><![CDATA[69DB852498AAE1498C04E20414021980]]></sign>
<total_fee><![CDATA[1]]></total_fee>
</xml>
假設商戶密鑰為:9d101c97133837e13dde2d32a5054abb
i:經過a過程URL鍵值對字典序排序後的字串string1為:
body=測試支付&mch_create_ip=127.0.0.1&mch_id=7551000001&nonce_str=
1409196838¬ify_url=http://227.0.0.1:9001/javak/&out_trade_no=141903606228&service=pay.weixin.jspay&total_fee=1
ii:經過b過程後得到sign為:
sign=md5(string1&key=9d101c97133837e13dde2d32a5054abb).toUpperCase
=md5(body=測試支付 &mch_create_ip=127.0.0.1&mch_id=7551000001&nonce_str=1409196838¬ify_url=
http://227.0.0.1:9001/javak/&out_trade_no=141903606228&service=pay.weixin.jspay&total_fee=1&key=
9d101c97133837e13dde2d32a5054abb ).toUpperCase()
="69DB852498AAE1498C04E20414021980"