md5签名 python_python接口自动化实现sign签名(MD5加密)

一,前序

今天在学习sign签名的的时候,了解了下常用的sign加密算法,突然心血来潮,想用python试着将签名生成的通用步骤用代码实现出来,虽然中间经历了一点小波折,请教了开发同事后,按照他给的思路建议,搞定了。我实现的是微信支付的签名算法规则。

二,加密业务规则

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

1.参数名ASCII码从小到大排序(字典序);

2.如果参数的值为空不参与签名;

3.参数名区分大小写;

4.验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。

5.微信接口可能增加字段,验证签名时必须支持增加的扩展字段。

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

md5签名 python_python接口自动化实现sign签名(MD5加密)_第1张图片

三,代码设计

3.1 参数类型确定

由微信支付签名生成规则描述可知,需要加密的参数数据是按照键值对的形式拼接,且参数名区分大小写,将参数数据定义为字典Dict类型特别合适,由于python本身区分大小写,字典键值也区分大小写。

#如代码所示:

>>> data={'q':'apple','Q':'orange'}

>>> data['q']

'apple'

>>> data['Q']

'orange'

3.2 参数设计

为了满足"参数的值为空不参与签名,传送的sign参数不参与签名,接口参数支持扩展”的签名算法规则,参数字典data在设计的时候除了要包含微信支付接口提供的必传参数外,另外我补充了参数值为空和参数名为sign的参数,如下:

#string1,string2用户扩展,增加参数名sign的参数

data={

'appid':'wxd930ea5d5a258f4f',

'mch_id':'10000100',

'device_info':'1000',

'body':'test',

'nonce_str':'ibuaiVcKdpRxkhJA',

'string1':'',

'string2':'',

'sign':'fdsfdhgjghjf'

}

3.3 自定义函数设计

参数data确定下来后,由于存在参数名为sign或者参数值为空的参数,这两种参数是不参与签名的。需要写一个函数,用于排除参数名为sign或者参数值为空的参数。另外参与签名的参数生成后,参数名要按照ASCII进行从小到大排序,然后跟参数值进行拼接,这里需要设计一个拼接函数。拼接函数需要实现参数名排序,python数据类型中,字典没有排序功能,但是列表有一个sort()函数可实现对象排序,因此要把字典的键值单独取出来存放到列表中进行排序,排序完成后再根据键名取字典对应的键值。

3.4 加密函数

需要加密的字符串生成后,可以利用python的hashlib模块对字符串进行加密。Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等,这里我用md5加密。加密后把字符串转换成大写,生成sign签名。

3.5 签名实现逻辑

1.将传的参数定义成字典类型数据A。

2.排除参数名为sign或者参数值为空的参数,另存为新的字典类型数据B。

3.将参数名用ASCII进行从小到大排序,参数名保存成列表对象。

4.用排序完成的参数名循环遍历字典数据B,跟参数值拼接。参数名1=参数值&参数名2=参数值&...

5.参数拼接完成,每个商户的key值也需要拼接,生成拼接API秘钥。

6.拼接完成的字符串,MD5加密,使用hashlib模块。

7.将加密得到的字符串所有字符转换为大写,得到sign值signValue。

四,代码实现

完整代码如下:

"""

接口名称:微信支付

实现目标:微信支付sign签名MD5加密

签名算法规则:

1.参数名ASCII码从小到大排序(字典序)

2.如果参数的值为空不参与签名

3.参数名区分大小写

4.验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验

5.微信接口可能增加字段,验证签名时必须支持增加的扩展字段

"""

#导入数据处理加密的包

import hashlib

keyString="192006250b4c09247ec02edce69f6a2d"

#所有发送或者接收到的数据定义为字典类型数据

data={

'appid':'wxd930ea5d5a258f4f',

'mch_id':'10000100',

'device_info':'1000',

'body':'test',

'nonce_str':'ibuaiVcKdpRxkhJA',

'string1':'',

'string2':'',

'sign':'fdsfdhgjghjf'

}

#定义函数作用:去除参数的值为空或者参数名为sign的数据,返回参与签名的字典类型数据

def GetSignData(data):

signData={}

for key, value in data.items():

if value != "" and key != "sign":

signData[key] = value

return signData

#对参数按照key=value的格式,并按照参数名ASCII字典序排序拼接成字符串stringA,最后拼接上key,返回拼接API密钥。

def SignString(signData,key):

#定义空列表

list=[]

# 定义空字符串

stringA=""

#循环遍历字典数据的键值,取出存放到列表中

for key in signData.keys():

list.append(key)

#对列表的对象进行排序,默认升序,即按照ASCII码从小到大排序

list.sort()

#循环遍历排序后的列表,根据键值取出字典键对应的值

for i in list:

stringA += i+"="+signData[i]+"&"

#参数拼接成需要加密的字符串

stringA += "key"+"="+keyString

return stringA

#调用GetSignData函数,获取参与签名的参数,返回新的字典数据

signData=GetSignData(data)

#调用函数,返回需要加密的字符串

signBody=SignString(signData,keyString)

print(signBody)

#创建对象md

md=hashlib.md5()

#对stringA字符串进行编码

md.update(signBody.encode('utf-8'))

#数据加密

signValue=md.hexdigest()

#把加密的结果,小写转换成大写,upper函数

signValue=signValue.upper()

print(signValue)

代码演示:

用python代码编写生成的sign签名与微信支付网页的签名一样,说明代码正确,如图:

md5签名 python_python接口自动化实现sign签名(MD5加密)_第2张图片

你可能感兴趣的:(md5签名,python)