PyJWT (Python)JWT 库
错误信息
The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
也可能输出为
- jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
PyJWT (Python) — jwt.exceptions.InvalidKeyError from HMACAlgorithm.prepare_key
含义
PyJWT 被要求把 PEM 格式的公钥、私钥或证书用作 HMAC 算法(HS256/384/512)的密钥,它拒绝了。之所以设置这道防护,是因为一类广为人知的 JWT 缺陷:如果验证方用同一个密钥参数同时接受 RS/ES 和 HS 算法,任何知道公钥的人都能为伪造的令牌计算出有效的 HMAC。在这里,令牌头部指定的 HMAC 算法恰好在你的允许列表之内。
原因
允许列表混用了 HMAC 算法和非对称算法
常见搭配公钥使用 `algorithms=["RS256", "HS256"]`,意味着 HS256 令牌会尝试把该公钥当作 HMAC 密钥。接受这样的令牌会让伪造的令牌通过验证;PyJWT 会阻止这种情况。
服务配置为 HS256,但持有的是 PEM
偶见配置中写的是 `JWT_ALGORITHM=HS256`,而 `JWT_KEY` 里却是一个 PEM 文件。先确定颁发者实际使用的是哪种方案,再让这两个值保持一致。
有人在试探验证方
偶见如果某个 API 的颁发者使用 RSA 或 ECDSA 签名,它却收到了 `alg: "HS256"` 的令牌,这是针对算法混淆弱点的典型探测。记录请求来源;这个错误说明探测失败了。
修复方法
- 1.
每个密钥只允许一个算法族
只传入颁发者使用的非对称算法及其公钥;HMAC 验证(如果确实需要)放在单独的代码路径中,并使用它自己的随机密钥。
python # Asymmetric issuer: allow only asymmetric algorithms with the public key. claims = jwt.decode(token, public_key, algorithms=["ES256"], audience="https://api.example.com") # Shared-secret tokens: a random secret, never a PEM, and only HMAC algorithms. claims = jwt.decode(token, HMAC_SECRET, algorithms=["HS256"], audience="internal")