通常公司对外的接口都会用到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"))