python-jose 通过可插拔的后端——纯 Python 的 ecdsa、pycryptodome 或 cryptography——实现 JWS、JWE、JWK 和 JWT;本次检查安装的是 cryptography 可选依赖。多年来 FastAPI 和 Flask 教程的推荐让它广为流行,但它的开发进展缓慢:3.4.0(2025年2月)距 3.3.0 将近四年,新项目通常改用 PyJWT、jwcrypto 或 joserfc。
jwt.decode() 中的 algorithms 是可选的,不传时算法取自令牌头部。结合2026年9月发布、在 3.5.0 中仍未修复的安全公告 GHSA-3qf3-8w2g-rqmx(CVE-2026-85394),这一点可被利用:防止把公钥用作 HMAC 密钥的检查能识别 PEM 和 OpenSSH 文本,却识别不出以 DER 字节形式提供的同一个密钥。本次检查复现了这个问题——以 DER 公钥为 HMAC 密钥的 HS256 令牌,在省略 algorithms 时用该公钥验证通过;而一旦传入 algorithms=["ES256"],就会被拒绝,报错 The specified alg value is not allowed。务必传入 algorithms;公钥要以 PEM 字符串形式保存;并用 JWT 密钥检测工具检查密钥。
它的算法集是 Python 库中最老旧的:只有 HS、RS 和 ES 系列。PS256、EdDSA 和 ES256K 会抛出 Algorithm … not supported.,因此已改用 Ed25519 或 RSA-PSS 的提供商所签发的令牌无法验证。ES256 也没有与 P-256 绑定:P-384 密钥在 ES256 头部下生成了 96 字节的签名,python-jose 能验证通过,但 jose 和 PyJWT 等其他库会拒绝。
ES256 签名是 64 字节的原始 r‖s,DER 签名会报错 Signature verification failed.;JWT 调试器会显示令牌采用的是哪种形式。除非像示例那样在 options 中设置 require_exp 和 leeway,否则 exp 是可选的,容差为零。
未签名的令牌被拒绝,报错 Unable to find an algorithm for key,即使传入 algorithms=["none"] 也一样。