python实现MD5签名和验签

本文介绍了MD5签名的原理,包括请求数据排序、加入appkey、MD5加密的流程。并提供了一种Python代码实现方式,用于生成和验证MD5签名。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理

请求方对请求数据按一定的规则排序,加上appkey码一起通过MD5加密生成签名,然后把请求数据和签名发给服务方,服务方拿到数据后,找到请求方的appkey,然后按同样的规则处理数据,并加上appkey通过MD5加密也生成签名,然后和请求方生成的签名去对比,如果值一样,签名验证通过。

MD5生成签名的流程

1.将请求字典中的空值,或者没必要的参数都去掉(如sign、sign_type等);
2.对字典进行排序(按ASCII码从小到大);
3.把字典中的所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
4.再加上appkey值,对形成的数据进行MD5加密,生成签名

python代码实现

class SignatureAndVerification(object):

    """MD5签名和验签"""

    @classmethod
    def data_processing(cls,data):
        """
        :param data: 需要签名的数据,字典类型
        :return: 处理后的字符串,格式为:参数名称=参数值,并用&连接
        """
        if "sign" in data:
            del data["sign"]
        if "sign_type" in data:
            del data["sign_type"]
        dataList = []
        for key in sorted(data):
            if data[key]:
                dataList.append("%s=%s" % (key, data[key]))
        return "&".join(dataList).strip()

    @classmethod
    def md5_sign(cls,data,api_key):
        """
        MD5签名
   
### Python 实现微信支付的签名功能 #### 一、签名生成逻辑 在微信支付场景下,签名是为了证数据的真实性安全性而设计的一种机制。以下是基于 `HMAC-SHA256` 的签名生成方法: ```python import hashlib import hmac from urllib.parse import urlencode def generate_signature(params, api_key): """ 使用 HMAC-SHA256 算法生成签名字符串。 :param params: 请求参数字典 (dict),需按照 key 排序后的键值对形式拼接成字符串 :param api_key: 商户 API 密钥 (string) :return: 签名结果 (string) """ sorted_params = [(k.lower(), v) for k, v in params.items() if v is not None and v != ""] sorted_params.sort(key=lambda x: x[0]) # 参数按字母顺序排列 query_string = urlencode(sorted_params).replace("+", "%20").replace("*", "%2A") + f"&key={api_key}" signature = hashlib.md5(query_string.encode('utf-8')).hexdigest().upper() return signature ``` 上述代码实现签名生成的核心部分[^1]。 --- #### 二、过程解析 当服务器收到微信返回的通知消息,需要对其进行操作来确认其真实性。具体流程如下: 1. **提取 XML 数据中的字段** 微信支付回调通常会以 XML 格式发送通知数据,因此第一步是从 XML 中读取所有必要的字段并去除 `<sign>` 字段。 2. **重新计算签名** 将这些字段按照特定规则排序后再次生成签名,并将其原始 `<sign>` 值对比。 3. **判断一致性** 如果两者一致,则表示该条消息合法;否则视为非法请求。 下面是具体的实现方式: ```python import xml.etree.ElementTree as ET def verify_sign(xml_data, api_key): """ 证来自微信支付的消息签名是否有效。 :param xml_data: 收到的 XML 格式的原始数据 (str) :param api_key: 商户 API 密钥 (string) :return: True 或 False 表示校成功否 (bool) """ root = ET.fromstring(xml_data) data_dict = {child.tag: child.text.strip() for child in root} sign_received = data_dict.pop("sign", "").strip().upper() # 提取出原有的 Sign 并移除掉它参后续运算 generated_sign = generate_signature(data_dict, api_key=api_key) return generated_sign == sign_received ``` 此函数完成了完整的工作流[^3]。 --- #### 三、实际应用案例&mdash;&mdash;订单状态更新接口 假设我们正在开发一个用于接收微信支付异步通知的服务端程序,可以这样编写路由及其处理器: ```python from flask import Flask, request, make_response app = Flask(__name__) @app.route('/wxpay/callback', methods=['POST']) def wxpay_callback(): raw_xml = request.data.decode('utf-8') api_key = 'your_merchant_api_secret' # 替换为自己的商户密钥 if verify_sign(raw_xml, api_key): # 对接收到的数据做初步的安全性检测 tree = ET.fromstring(raw_xml) result_code = tree.findtext('.//result_code') or '' out_trade_no = tree.findtext('.//out_trade_no') or '' if result_code.upper() == "SUCCESS": # 更新数据库记录交易完成的状态... response_content = """<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>""" return make_response(response_content, 200, {'Content-Type': 'application/xml'}) else: pass # 处理失败情况... return "", 400 # 若未通过检则直接丢弃当前 POST 请求 ``` 以上展示了如何构建一个能够响应微信官方推送事件的应用实例。 --- #### 四、注意事项 - 在生产环境中务必妥善保管好您的 Merchant Key 其他敏感配置项; - 所有涉及金额的操作都应严格遵循双写原则(即先记账再反馈),防止因网络延迟等原因造成资金损失风险; - 定期检查最新版 SDK 文档是否有更优实践可供采纳。 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值