签名生成
api 签名(sign)设计文档
版本 | 日期 | 改动说明 | 审核人 | 拟定人 |
---|---|---|---|---|
V1.0.0 | 2019-03-20 | 初步拟定 |
1、背景
1. 在公共网络环境(如: WIFI、非家庭网络、非办公网络等)网络请求是不安全的,一切基于HTTP协议的请求/响应(Resquest/Response)都是可以背截获、篡改、重发的。
2. 对外开放的接口安全性要求:防伪装攻击、防篡改攻击、防重发攻击
2、实现思路
1. app 端根据用户请求的唯一凭证 (app_key 或token) 再拼接上请求接口需要的参数,再拼接上时间戳(timestamp) 最终生成MD5编码,再转化成全部大写的形式生成签名(sign)。在请求的app接口的信息中将为一凭证(app_key 或token)和 sign,和时间戳(timestamp)一同提交到服务。
2. 服务端验证:
(1)判断token 是否有效
(2)判断服务器端根据规则生成的sign 和用户传过来的sign是否相同
(3)判断时间戳(timestamp)是否在有效期内
3、设计方案
签名算法过程:
1.对除签名外的所有请求参数按key做的升序排列,value无需编码。 (假设当前时间的时间戳是12345678)
例如:有c=3,b=2,a=1 三个参,另加上时间戳后, 按key排序后为:a=1,b=2,c=3,_timestamp=12345678。
2 .把参数名和参数值连接成字符串,得到拼装字符:a1b2c3_timestamp12345678
3. 用申请到的token 连接到接拼装字符串头部,然后进行32位MD5加密,最后将到得MD5加密摘要转化成大写。
示例:假设token=test,md5(testa1b2c3_timestamp12345678),取得MD5摘要值 C5F3EB5D7DC2748AED89E90AF00081E6
python代码实现
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、根据规则生成sign
2、参数传递方式
sign 放在http请求的header中
key | value | 是否必填 |
---|---|---|
sign | CA116DE1DC8B33B7A73E0A1CF99CD92B | 是 |
token、timestamp 放在http请求的body中
key | value | 是否必填 |
---|---|---|
token | test | 是 |
timestamp | 123456789 | 是 |