• python接口自动化-实现sign签名(MD5加密)


    本文内容皆为作者原创,码字不易,如需转载,请注明出处:https://www.cnblogs.com/temari/p/13513636.html

    一,前序

    今天在学习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。

    参考网址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3

    三,代码设计

    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签名与微信支付网页的签名一样,说明代码正确,如图:

  • 相关阅读:
    约束
    TCL(事务控制语言)
    MySQL常见约束
    “三大范式”及数据库设计
    同义词(别名)
    分享35个非常漂亮的单页网站设计案例
    Eclipse智能提示 (原创)
    java架构师之路:JAVA程序员必看的15本书的电子版下载地址
    Java初级学习笔记
    Java程序的汉化
  • 原文地址:https://www.cnblogs.com/temari/p/13513636.html
Copyright © 2020-2023  润新知