跳到主要内容
ecdsa.com
jwks-rsa (Node.js)JWKS 与密钥发现

错误信息

Unable to find a signing key that matches '2026-10-rotated'

也可能输出为

  • error in secret or public key callback: Unable to find a signing key that matches '2026-10-rotated'
  • SigningKeyNotFoundError: Unable to find a signing key that matches
  • No KID specified and JWKS endpoint returned more than 1 key

引号中的值是令牌的 `kid`(如果头部中没有,则为 `'undefined'`)。通过带回调的 `jwt.verify()` 调用时,文本前面会加上“error in secret or public key callback: ”。不带 `kid` 的令牌遇到包含多个密钥的密钥集时,会报错“No KID specified and JWKS endpoint returned more than 1 key”。

jwks-rsa (Node.js) — SigningKeyNotFoundError, often wrapped by jsonwebtoken or express-jwt

含义

jwks-rsa 下载了密钥集,但其中没有任何一个可用的签名密钥带有令牌头部中的 `kid`(即引号中的值)。令牌本身可能完全有效——只是验证方没有签名它的那个密钥。通过 jsonwebtoken 的密钥回调使用 jwks-rsa 时,消息前面会加上“error in secret or public key callback:”前缀。

原因

修复方法

  1. 1.

    列出已发布的 kid

    解码令牌头部,把其中的 `kid` 与 `jwksUri` 处的密钥对比。如果 `kid` 在其中,错误却依然存在,说明该密钥被过滤掉了——检查它的 `use` 和 `kty`。

    bash
    # kids the provider publishes (jwks-rsa ignores keys with use "enc" and non RSA/EC/OKP keys)
    curl -s https://tenant.example.com/.well-known/jwks.json | jq '.keys[] | {kid, kty, use, alg}'
  2. 2.

    创建一个启用缓存和速率限制的客户端

    启用缓存的模块级客户端会在出现新的 `kid` 时重新获取密钥集;当攻击者发送随机 `kid` 值时,它还能保护提供商免受大量请求的冲击。

    js
    import jwksRsa from "jwks-rsa";
    
    // One client per process; unknown kids trigger a refetch, bounded by the rate limit.
    export const jwksClient = jwksRsa({
      jwksUri: "https://tenant.example.com/.well-known/jwks.json",
      cache: true,
      cacheMaxAge: 10 * 60 * 1000,
      rateLimit: true,
      jwksRequestsPerMinute: 10,
    });

相关错误

浏览完整的签名错误库