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

跨语言RSA-SHA256-PSS签名验证失败:JSON对象验证不通过

Python与Go RSA-SHA256-PSS签名互验失败的解决方法

问题根源

签名验证失败的核心原因是Python和Go对JSON对象/结构体的序列化结果不一致:

  • Python的json.dumps默认会在键值对、逗号后添加空格(如{"name": "Foo", "age": 12})
  • Go的json.Marshal(包括你使用的goccy/go-json默认行为)生成的是无空格的紧凑JSON(如{"name":"Foo","age":12})

两者生成的字节串完全不同,而签名是基于序列化后的字节串计算的,自然无法通过验证。

修复步骤

1. 修改Python代码,生成紧凑无空格的JSON

在json.dumps中指定separators=(',', ':')参数,强制生成和Go一致的紧凑JSON:

def sign_user(message) -> str:
    # 关键修改:生成无空格的紧凑JSON
    message_json = json.dumps(message, separators=(',', ':'))
    message_byts = message_json.encode("utf-8")
    # 后续加载私钥、签名的代码保持不变
    key_file = open("private_key.pem", "rb")
    private_key = serialization.load_pem_private_key(
        key_file.read(), password=None, backend=default_backend()
    )
    signature = private_key.sign(
        message_byts,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256(),
    )

    signature_base64 = base64.b64encode(signature).decode("utf-8")
    print("\n\n", signature_base64, "\n\n")
    return signature_base64

2. 确保Go序列化规则匹配

你的Go代码使用goccy/go-json的json.Marshal默认就是紧凑序列化,无需修改,但要确保没有开启任何格式化(如缩进)选项:

func verifySignatureUser(sign string, data User){
    // 默认生成紧凑JSON,和修改后的Python代码输出一致
    dataBytes, err := json.Marshal(data)
    if err != nil {
        fmt.Print(err)
    }
    verified, err := VerifySignature(sign, dataBytes)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(verified)
}

3. 额外校验项

  • 键顺序:确保Python字典的键顺序和Go结构体的字段顺序完全一致(你的代码中已经满足:name→age→email)
  • 数据类型:Python的int和Go的uint序列化后无差异,若涉及浮点型需保证精度一致
  • 编码:两边均使用UTF-8编码(代码已满足)

验证

修改Python代码后重新生成签名,用Go代码验证即可通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:22:33