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

将Node.js crypto签名逻辑转为Python jwt实现时出现签名错误的技术问询

问题分析与解决方案

你的问题出在错误使用了JWT编码来实现单纯的RSA-SHA256签名。Node.js代码是直接对payload的JSON字符串进行签名,而jwt.encode会生成符合JWT规范的令牌(包含header、payload和签名三部分,用.分隔),两者的签名输入完全不同,自然会导致签名不匹配。

Node.js代码的核心逻辑

先拆解一下网关提供的Node.js代码做了什么:

  1. 读取PEM格式的私钥
  2. 创建RSA-SHA256签名器
  3. 将payload序列化为无空格分隔的JSON字符串,并去除首尾空白字符
  4. 对该字符串进行签名,输出Base64编码的结果

正确的Python实现

要和Node.js行为完全一致,需要严格对齐每一步的操作:

1. 安装依赖

确保你已经安装了cryptography库(这是Python处理加密操作的标准库):

pip install cryptography

2. 完整Python代码

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

# 定义需要签名的payload
actual = {
    "IntraTransferRqHeader": {
        "CorporateID": "XXX",
        "CorpReferenceNumber": "47165454456"
    },
    "IntraTransferRqBody": {
        "AccountNumber": "05100004061100",
        "DebitCurrency": "SAR",
        "BeneficiaryAccountNumber": "30008776337526",
        "TransferAmount": "100.23",
        "TransferCurrency": "SAR",
        "Description": "Transfer fund to beneficiary",
        "AMLPurposeCode": "BC"
    }
}

# 读取PEM私钥
private_key_path = "/etc/ssl/nginx/snbcsr.key"
with open(private_key_path, "rb") as key_file:
    private_key = serialization.load_pem_private_key(
        key_file.read(),
        password=None,
        backend=None  # 无需显式指定后端(cryptography v3.0+默认自动处理)
    )

# 生成与Node.js一致的JSON字符串:无空格分隔符+去除首尾空白
payload_str = json.dumps(actual, separators=(',', ':')).strip()

# 执行RSA-SHA256签名
signature_bytes = private_key.sign(
    payload_str.encode("utf-8"),
    padding.PKCS1v15(),  # Node.js的createSign默认使用PKCS#1 v1.5填充
    hashes.SHA256()
)

# 转换为Base64编码的签名(与Node.js输出格式一致)
signature_base64 = base64.b64encode(signature_bytes).decode("utf-8")

print(signature_base64)

关键注意事项

  • JSON字符串一致性:Node.js的JSON.stringify默认生成无空格的JSON(如{"a":1,"b":2}),而Python的json.dumps默认会添加空格(如{"a": 1, "b": 2})。必须用separators=(',', ':')参数消除空格,否则签名输入会不一致。
  • 填充算法:Node.js的crypto.createSign("RSA-SHA256")默认使用PKCS#1 v1.5填充,Python中对应padding.PKCS1v15()。
  • 字符编码:确保字符串以UTF-8编码为字节流后再签名,与Node.js的默认编码一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 10:39:10