通常公司對外的接口都會用到sign簽名,對不一樣的客戶提供不一樣的apikey ,這樣能夠提升接口請求的安全性,避免被人抓包後亂請求。
sign簽名是一種很常見的方式python
簽名參數sign生成的方法api
假設傳輸的數據是http://www.xxx.com/interface.aspx?sign=sign_value&p2=v2&p1=v1&method=cancel&p3=&pn=vn
(實際狀況最好是經過post方式發送),
其中sign參數對應的sign_value就是簽名的值。
第一步,拼接字符串,首先去除sign參數自己,而後去除值是空的參數p3,剩下p2=v2&p1=v1&method=cancel&pn=vn,
而後按參數名字符升序排序,method=cancel&p1=v1&p2=v2&pn=vn.
第二步,而後作參數名和值的拼接,最後獲得methodcancelp1v1p2v2pnvn
第三步,在上面拼接獲得的字符串後加上驗證密鑰key,咱們假設是abc,獲得新的字符串methodcancelp1v1p2v2pnvnabc
第四步,而後將這個字符串換爲小寫進行md5計算,假設獲得的是abcdef,這個值即爲sign簽名值。
注意,計算md5以前請確保接口與接入方的字符串編碼一致,如統一使用utf-8編碼或者GBK編碼,若是編碼方式不一致則計算出來的簽名會校驗失敗。安全
咱們假設提供的apikey爲12345678,請求的body參數爲函數
body = { "username": "test", "password": "123456", "mail": "", "sign": "簽名後的值" }
使用python實現簽名post
import hashlib apikey = "12345678" # 驗證密鑰,由開發提供 body = { "username": "test", "password": "123456", "mail": "" } # 列表生成式,生成key=value格式 a = ["".join(i) for i in body.items() if i[1] and i[0] != "sign"] print(a) # 參數名ASCII碼從小到大排序 strA = "".join(sorted(a)) print(strA) # 在strA後面拼接上apiKey獲得striSignTemp字符串 striSignTemp = strA+apikey # 將strSignTemp字符串轉換爲小寫字符串後進行MD5運算 # MD5加密 def jiamimd5(src): m = hashlib.md5() m.update(src.encode('UTF-8')) return m.hexdigest() sign = jiamimd5(striSignTemp.lower()) print(sign) # 獲得sign簽名後新的body值 body["sign"] = sign print(body)
運行結果編碼
['usernametest', 'password123456'] password123456usernametest 1aca01806e93bb408041965a817666af {'username': 'test', 'password': '123456', 'mail': '', 'sign': '1aca01806e93bb408041965a817666af'}
把上面記流水帳的代碼,寫成一個函數,方便調用加密
import hashlib def sign_body(body, apikey="12345678"): '''請求body sign簽名''' # 列表生成式,生成key=value格式 a = ["".join(i) for i in body.items() if i[1] and i[0] != "sign"] # print(a) # 參數名ASCII碼從小到大排序 strA = "".join(sorted(a)) # print(strA) # 在strA後面拼接上apiKey獲得striSignTemp字符串 striSignTemp = strA+apikey # 將strSignTemp字符串轉換爲小寫字符串後進行MD5運算 # MD5加密 def jiamimd5(src): m = hashlib.md5() m.update(src.encode('UTF-8')) return m.hexdigest() sign = jiamimd5(striSignTemp.lower()) # print(sign) # 獲得sign簽名後新的body值 body["sign"] = sign # print(body) return body if __name__ == '__main__': apikey = "12345678" # 驗證密鑰,由開發提供 body = { "username": "test", "password": "123456", "mail": "", "sign": "" } print(sign_body(body, apikey="12345678"))