You need to enable JavaScript to run this app. 自行实现的JWT签名无法通过工具验证,问题出在哪里?
优惠活动
大模型
产品
解决方案
定价
更多

自行实现的JWT签名无法通过工具验证,问题出在哪里?

问题排查

    1. 签名流程使用了错误的Node.js Crypto API
      你调用的crypto.privateEncrypt是用于RSA加密场景的API,不符合JWT RS256签名的标准要求:RSASSA-PKCS1-v1_5签名规范要求对哈希值封装ASN.1 DigestInfo结构后再执行私钥运算,privateEncrypt不会自动添加该结构,直接加密原始哈希值会导致签名结构不符合标准。
    1. 输出编码不符合JWT规范
      JWT要求签名部分使用URL安全的Base64编码(Base64URL),你当前使用的普通Base64编码存在+、/、=等JWT不允许的字符,会导致校验失败。
    1. 输入参数校验缺失
      需要确认传入的input参数已经是Base64URL编码的header + "." + Base64URL编码的payload的拼接结果,输入格式不符合JWT要求也会直接导致签名校验失败。

修复方案

推荐直接使用Node.js Crypto标准的签名APIcrypto.createSign,自动符合RS256的签名规范,示例实现如下:

const createJwtRs256Signature = (headerPayloadStr: string, privateKey: string) => {
  // 初始化RS256签名器
  const sign = crypto.createSign('RSA-SHA256');
  // 写入待签名的 header.payload 内容
  sign.update(headerPayloadStr);
  sign.end();
  // 生成签名后转Base64URL编码
  const signature = sign.sign(privateKey)
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
  return signature;
};

如果要坚持用底层API实现,需要手动给SHA256哈希值添加对应的DigestInfo前缀,SHA256对应的前缀固定为Buffer.from([0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20]),把前缀和你生成的哈希值拼接后再传入privateEncrypt即可,不过该方案容错性低,更推荐使用标准的Sign API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 06:06:04