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

Node.js Crypto签名不一致问题排查求助

问题原因与解决办法

你遇到的每次签名结果不一致的问题,核心原因是RSA-PSS签名机制会使用随机生成的盐值——这是该签名方案的设计特性,用于提升安全性,所以即使是同一明文和私钥,每次生成的签名也会不同。

不过你的测试用例要求两次签名完全一致,这说明要么你误解了Paybis API的签名要求,要么需要调整签名参数来匹配对方的预期:

1. 确认Paybis的签名 padding 要求

先核对Paybis合作伙伴API的签名规范:

  • 如果文档明确要求使用RSA-PSS,那对方的验证逻辑应该兼容随机盐值的签名(公钥验证会自动处理盐值),你的测试用例本身不合理,因为RSA-PSS签名就是非确定性的。
  • 如果文档要求的是传统的PKCS#1 v1.5 padding,那换成该padding后,同一明文和私钥的签名会完全一致,因为这种方案没有随机盐值。

2. 调整代码适配需求

情况一:Paybis确实要求RSA-PSS

如果API明确使用RSA-PSS,你的测试用例应该改为验证签名有效性,而非对比签名字符串:

// 新增验证函数
const verifySignature = (publicKey: Buffer, verifiableData: string, signature: string) => {
  return crypto.verify(
    'sha512',
    Buffer.from(verifiableData),
    {
      key: publicKey,
      padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
    },
    Buffer.from(signature, 'base64')
  );
};

// 测试验证逻辑而非签名一致性
const verifiableData = '{"event":"VERIFICATION_STATUS_UPDATED","data":{"partnerUserId":"e18fb964-fd9a-4de7-96c4-1lclszzd","status":"started"},"timestamp":1654073212}';
const signature = signRequest(privateKey);
const isValid = verifySignature(publicKey, verifiableData, signature);
expect(isValid).to.be.true; // 这才是合理的测试逻辑

情况二:Paybis要求PKCS#1 v1.5 padding

修改signRequest中的padding参数:

const signature = crypto.sign(
    'sha512',
    Buffer.from(verifiableData),
    {
        key: privateKey,
        padding: crypto.constants.RSA_PKCS1_PADDING, // 替换为PKCS#1 v1.5 padding
    },
);

修改后,同一明文和私钥生成的签名会完全一致,你的原测试用例就能通过。

3. 额外注意事项

  • 确保verifiableData字符串和Paybis要求的完全一致:包括空格、引号、键的顺序,动态生成时建议用JSON.stringify严格序列化,避免额外格式差异。
  • 你的私钥PEM格式合法,无需调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:15:38