jwks-rsa (Node.js)JWKS 与密钥发现
错误信息
The JWKS endpoint did not contain any signing keys
也可能输出为
- The JWKS endpoint did not contain any keys
jwks-rsa (Node.js) — JwksError from getSigningKey()
含义
JWKS 端点返回了密钥,但经过过滤后,没有一个能用来验证签名。jwks-rsa 只保留满足以下条件的密钥:`use` 为 `"sig"` 或不存在,`kty` 为 RSA、EC 或 OKP,并且能成功导入为公钥。其他一切——加密密钥、对称密钥、格式错误的 JWK 或私钥 JWK——都会被丢弃。与之相近的消息“did not contain any keys”表示 `keys` 数组本身为空或缺失。
原因
只发布了加密密钥
常见有些提供商为加密密钥(用于 JWE)和签名密钥分别提供端点。如果配置的是加密密钥的 URL,得到的就是标记为 `use: "enc"` 的密钥,这类密钥绝不能用来验证签名。
对称或未知的密钥类型
偶见由 `kty: "oct"` 密钥(HMAC 密钥——它们永远不应该被发布)或 jwks-rsa 不支持的密钥类型组成的密钥集,会被整个过滤掉。
私钥 JWK 或格式错误的 JWK
偶见无法导入的密钥(缺少 `n`/`e`、base64url 有误、曲线不受支持)会被静默跳过;因包含 `d` 而被导入为私钥的密钥也一样。私钥一旦发布,同时也就是一起密钥泄露事件。
该 URL 返回的是别的 JSON
偶见OpenID 发现文档或错误对象中没有 `keys` 数组;这时 jwks-rsa 会报告端点中根本没有密钥。
修复方法
- 1.
查看每个密钥的 kty、use 和 alg
一行 jq 命令就能显示每个密钥被过滤的原因。出现 `has_private: true` 的行,说明密钥集泄露了私钥:删除它,并轮换该密钥。
bash curl -s "$JWKS_URI" | jq '.keys[] | {kid, kty, use, alg, crv, has_private: has("d")}' - 2.
至少发布一个签名密钥
如果端点由你运营,就把每个在用的签名密钥都放进去,并带上 `use: "sig"`、唯一的 `kid` 和对应的 `alg`。加密密钥可以放在同一个密钥集中,只要标记为 `use: "enc"`。
json { "keys": [ { "kty": "RSA", "kid": "sig-2026-10", "use": "sig", "alg": "RS256", "n": "…", "e": "AQAB" }, { "kty": "RSA", "kid": "enc-2026", "use": "enc", "alg": "RSA-OAEP-256", "n": "…", "e": "AQAB" } ] }