You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python处理Webhook时使用公钥HMAC签名验证失败问题求解

Webhook签名校验失败修复方案

以下是你代码存在的核心问题及修复方案:

  • 算法选型错误:HMAC-SHA256是对称签名算法,仅适用于共享密钥场景。你提供的是RSA公钥,说明平台采用非对称签名方案,应使用SHA256WithRSA验签,而非HMAC算法。
  • 载荷构造错误:你将event_body解析为字典后再通过json.dumps()序列化,Python默认序列化规则(空格、转义处理)和平台签名时使用的原始请求体字符串不一致,直接导致载荷错误。请直接使用Webhook推送的原始请求体字符串,不要做解析再序列化操作。
  • 多余换行符问题:多数平台的待签名串末尾不需要额外添加\n,你当前构造payload_to_sign时末尾添加的换行符不符合通用规则。
  • 公钥处理错误:你将RSA公钥解码为DER格式后直接传入HMAC作为密钥,不符合RSA验签的公钥加载逻辑。

修复后示例代码

首先安装依赖库:
pip install cryptography

代码实现:

import base64
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature

# 直接使用完整PEM格式公钥,无需手动截取内容
Publickey = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVAMXVTMIuttHcP1kvSk9V39S7
BqDbY+LC9JfwMzyoubo3fdsqBf4EmB1PfBUigcOL5YBqMKGEE6xmVw6SXCTH4JwX
dqJ4IRiXf76YMt6PB0dMzu/qCmhaGFGkqT6vJM0hHyEbtS/P3FR9ZU+eaOvynLWb
FvXTzIoctZM1IvDrCwIDAQAB
-----END PUBLIC KEY-----'''

# 加载RSA公钥
public_key = serialization.load_pem_public_key(
    Publickey.encode('utf-8')
)

WebhookSignature = "VtniwOFAi4oBKFnvHhY6UZ+wPARf7+yWVbE61Hc7JVdRgqKJ40Yk9k5Gb2Y0S0VLUYOOOhUNUsD7R8GDEr6WH84sAEf8bXa1xYMiyjgeGleTg1MxRJCtrHcxMeMCEXPWmKTeLhn6O+cdvDGq4ZpcTTiQnEvk5xHPcxFrBT637zg="
WebhookTimestamp = 1611232922428
WebhookNonce = "5RhaTrZPhknNv0kDSA2UQ67cPMVNS4sA"
# 直接使用Webhook推送的原始请求体字符串,不要解析再序列化
raw_event_body = '{"bizType":"PAY","data":"{\\"merchantTradeNo\\":\\"9825382937292\\",\\"totalFee\\":0.88000000,\\"transactTime\\":1619508939664,\\"currency\\":\\"EUR\\",\\"commission\\":0,\\"openUserId\\":\\"1211HS10K81f4273ac031\\",\\"productType\\":\\"Food\\",\\"productName\\":\\"Ice Cream\\",\\"tradeType\\":\\"WEB\\",\\"transactionId\\":\\"M_R_282737362839373\\"}","bizId":29383937493038367292,"bizStatus":"PAY_SUCCESS"}'

# 按规则拼接待签名串,可根据平台文档确认是否需要末尾加换行
payload_to_sign = f"{WebhookTimestamp}\n{WebhookNonce}\n{raw_event_body}"

# 解码收到的签名
decode_signature = base64.b64decode(WebhookSignature)

try:
    # 执行RSA-SHA256验签
    public_key.verify(
        decode_signature,
        payload_to_sign.encode('utf-8'),
        padding.PKCS1v15(),
        hashes.SHA256()
    )
    print("签名校验通过")
except InvalidSignature:
    print("签名校验失败")

内容的提问来源于stack exchange,提问作者Pun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:24:09