You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Node.js中验证由phpseclib签名的支付网关RSA签名

在Node.js中验证支付网关的RSA签名

嘿,我明白你现在要在Node.js应用里处理支付网关的回调,验证RSA签名对吧?我帮你把给出的PHP示例转换成Node.js的实现,步骤超清晰的~

首先先理清楚PHP示例里的核心逻辑:从POST参数里拿到paymentsignature,对两者做base64解码,再用网关提供的公钥验证签名。Node.js里我们可以用内置的crypto模块来完成这些操作,不需要额外装第三方包,很方便。

1. 具体实现代码

假设你用Express框架处理HTTP请求(如果不用的话,调整请求解析部分即可),完整代码如下:

const crypto = require('crypto');
const express = require('express');
const app = express();

// 解析POST表单数据,要是回调是JSON格式就换成express.json()
app.use(express.urlencoded({ extended: true }));

// 替换成支付网关给你的公钥,必须是标准PEM格式(包含首尾标记行)
const PAYMENT_GATEWAY_PUB_KEY = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...(这里填网关提供的公钥内容)
-----END PUBLIC KEY-----`;

// 支付回调接口
app.post('/payment-callback', (req, res) => {
  try {
    // 1. 从POST参数里取出payment和signature
    const { payment, signature } = req.body;

    if (!payment || !signature) {
      return res.status(400).send('缺少必要的支付参数');
    }

    // 2. 对参数做base64解码,对应PHP的base64_decode
    const decodedPaymentData = Buffer.from(payment, 'base64');
    const decodedSignature = Buffer.from(signature, 'base64');

    // 3. 创建签名验证实例,注意算法要和网关完全一致!
    // 常见的是RSA-SHA256,要是网关用SHA1就改成RSA-SHA1
    const verifier = crypto.createVerify('RSA-SHA256');

    // 4. 传入要验证的原始数据(解码后的payment内容)
    verifier.update(decodedPaymentData);

    // 5. 执行验证,返回布尔值
    const isSignatureValid = verifier.verify(PAYMENT_GATEWAY_PUB_KEY, decodedSignature);

    if (isSignatureValid) {
      // 签名验证通过,这里写你的支付成功逻辑
      console.log('支付结果验证通过,处理后续流程');
      res.status(200).send('success');
    } else {
      // 签名无效,拒绝处理
      console.log('支付签名验证失败,可能是数据被篡改');
      res.status(403).send('invalid signature');
    }
  } catch (error) {
    console.error('签名验证过程出错:', error);
    res.status(500).send('服务器内部错误');
  }
});

app.listen(3000, () => {
  console.log('服务启动,监听端口3000');
});

2. 几个关键注意事项

  • 公钥格式要正确:一定要确保公钥是标准的PEM格式,也就是必须包含-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----这两行,要是网关给你的是纯文本的公钥(没有这些标记),记得手动加上,不然crypto模块会直接报错。
  • 签名算法必须匹配:支付网关用什么算法签名,你就得用对应的算法验证。比如PHP示例里如果用的是SHA1,那Node.js里就要改成RSA-SHA1,大部分网关现在用的是SHA256,所以示例里用了RSA-SHA256,一定要和网关确认清楚。
  • 数据编码别搞错:Node.js里的Buffer.from(xxx, 'base64')和PHP的base64_decode是完全对应的,别用错编码格式。
  • 请求解析适配:如果支付网关的回调是JSON格式的POST请求,记得把express.urlencoded换成express.json(),不然拿不到正确的参数。

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

火山引擎 最新活动