api 簽名(sign)設計文檔
版本 | 日期 | 改動說明 | 審核人 | 擬定人 |
---|---|---|---|---|
V1.0.0 | 2019-03-20 | 初步擬定 |
1站楚、背景
? 1. 在公共網(wǎng)絡環(huán)境(如: WIFI阵翎、非家庭網(wǎng)絡双絮、非辦公網(wǎng)絡等)網(wǎng)絡請求是不安全的,一切基于HTTP協(xié)議的請求/響應(Resquest/Response)都是可以背截獲够吩、篡改比然、重發(fā)的。
? 2. 對外開放的接口安全性要求:防偽裝攻擊周循、防篡改攻擊强法、防重發(fā)攻擊
2、實現(xiàn)思路
? 1. app 端根據(jù)用戶請求的唯一憑證 (app_key 或token) 再拼接上請求接口需要的參數(shù)湾笛,再拼接上時間戳(timestamp) 最終生成MD5編碼饮怯,再轉(zhuǎn)化成全部大寫的形式生成簽名(sign)。在請求的app接口的信息中將為一憑證(app_key 或token)和 sign嚎研,和時間戳(timestamp)一同提交到服務蓖墅。
? 2. 服務端驗證:
? (1)判斷token 是否有效
? (2)判斷服務器端根據(jù)規(guī)則生成的sign 和用戶傳過來的sign是否相同
? (3)判斷時間戳(timestamp)是否在有效期內(nèi)
3、設計方案
簽名算法過程:
? 1.對除簽名外的所有請求參數(shù)按key做的升序排列,value無需編碼临扮。 (假設當前時間的時間戳是12345678)
? 例如:有c=3,b=2,a=1 三個參论矾,另加上時間戳后, 按key排序后為:a=1杆勇,b=2贪壳,c=3,_timestamp=12345678蚜退。
? 2 .把參數(shù)名和參數(shù)值連接成字符串闰靴,得到拼裝字符:a1b2c3_timestamp12345678
? 3. 用申請到的token 連接到接拼裝字符串頭部彪笼,然后進行32位MD5加密,最后將到得MD5加密摘要轉(zhuǎn)化成大寫传黄。
? 示例:假設token=test杰扫,md5(testa1b2c3_timestamp12345678),取得MD5摘要值 C5F3EB5D7DC2748AED89E90AF00081E6
python代碼實現(xiàn)
?
In [20]: def md5(content):
...: if isinstance(content, str):
...: content = content.encode("utf-8")
...: hash = hashlib.md5()
...: hash.update(content)
...: return hash.hexdigest()
parame_dict = {'token': 'test',
'invoice_i':'af5b769c9ba5456306468e61719a09ca',
'timestamp': 123456789}
token = parame_dict.pop('token')
sign_str = token + ''.join([str(item[0])+str(item[1]) for item in sorted(parame_dict.items(), key=lambda d: d[0])])
sign = md5(sign_str).upper()
print(sign)
'CA116DE1DC8B33B7A73E0A1CF99CD92B'
4膘掰、app端使用方法
?
? 1章姓、根據(jù)規(guī)則生成sign
? 2、參數(shù)傳遞方式
? sign 放在http請求的header中
?
key | value | 是否必填 |
---|---|---|
sign | CA116DE1DC8B33B7A73E0A1CF99CD92B | 是 |
? token识埋、timestamp 放在http請求的body中
key | value | 是否必填 |
---|---|---|
token | test | 是 |
timestamp | 123456789 | 是 |