在IBM i(AS400/iSeries)上用OpenSSL生成JWT签名失败求助
JWT RSA-PSS签名验证失败问题排查与解决
你遇到的签名验证失败,核心原因是OpenSSL签名流程未完全匹配JWT的RSASSA-PSS标准要求,以下是具体排查点和修复方案:
1. 签名命令未匹配JWT的算法参数
你生成密钥时指定了RSA-PSS和32位salt长度,但签名时如果未明确指定哈希算法、PSS填充模式及salt长度,OpenSSL会使用默认值,和jwt.io的PS256(SHA-256+RSA-PSS)配置不兼容。
正确签名命令:
必须确保签名输入是Header与Payload经过Base64URL编码后用.连接的原始字符串,且指定完整的PSS参数:
# 假设header.payload是Base64URL编码后的拼接字符串,直接作为输入 echo -n "header.payload" | openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sign key.pem -out signature.bin
2. 签名结果编码不符合JWT要求
OpenSSL生成的signature.bin是二进制格式,JWT要求签名必须是Base64URL编码(替换+为-、/为_,删除末尾所有=),直接复制二进制或普通Base64内容都会导致验证失败。
正确转换命令:
# 二进制转Base64,再转Base64URL openssl base64 -in signature.bin | tr '+/' '-_' | tr -d '=\n' > signature.b64url
3. JWT Header算法声明错误
如果你的JWT Header中alg字段写的是RS256(普通RSA签名),jwt.io会用错误的算法验证RSA-PSS签名,必然失败。
正确Header示例:
{ "alg": "PS256", "typ": "JWT" }
4. OpenSSL 3.0的参数兼容性问题
OpenSSL 3.0对RSA-PSS的默认处理逻辑与旧版本不同,必须确保签名时的saltlen参数和密钥生成时的rsa_pss_saltlen:32完全一致,否则签名会不兼容。
验证流程
- 用上述正确命令重新生成签名,并转换为Base64URL格式;
- 拼接完整JWT:
base64url_header.base64url_payload.base64url_signature; - 在jwt.io中选择
PS256算法,粘贴从cert.pem提取的公钥(命令:openssl x509 -in cert.pem -pubkey -noout > pubkey.pem),验证即可通过。
内容的提问来源于stack exchange,提问作者baphomet
相关产品推荐
相关产品推荐

