本文へスキップ
ecdsa.com
jose (JavaScript)JWKS と鍵のディスカバリ

エラーメッセージ

no applicable key found in the JSON Web Key Set

jose (JavaScript) — JWKSNoMatchingKey, code ERR_JWKS_NO_MATCHING_KEY

このエラーの意味

jose は渡された鍵セット(JSON Web Key Set)を調べましたが、このトークンの検証に使ってよい鍵が見つかりませんでした。鍵が対象になるのは、次の条件をすべて満たす場合だけです。`kid` がトークンのヘッダーの `kid` と等しいこと(トークンにある場合)、`kty` がトークンの `alg` に適合すること、`alg`(ある場合)がトークンの `alg` と等しいこと、`crv` が一致すること(ES256 なら P-256)、`use` がないか `"sig"` であること、`key_ops`(ある場合)に `"verify"` が含まれていること。暗号処理は一切実行されておらず、失敗したのは鍵の選択の段階です。

発生する理由

修正方法

  1. 1.

    トークンの kid を公開されている鍵と比較する

    保護ヘッダーをデコードし、公開されている鍵を `kid`、`alg`、`kty`、`crv`、`use` とともに一覧表示してください。`kid` が鍵セットにない場合は、ローテーションか鍵セットの取り違えです。ある場合は、メタデータのフィールドを確認してください。

    bash
    # kid and alg the token asks for
    python3 -c 'import base64,json,sys; h=sys.argv[1].split(".")[0]; print(json.loads(base64.urlsafe_b64decode(h + "=" * (-len(h) % 4))))' "$TOKEN"
    # kid, alg, kty, crv, use of every key the issuer publishes
    curl -s https://issuer.example.com/.well-known/jwks.json | jq '.keys[] | {kid, alg, kty, crv, use}'
  2. 2.

    鍵を固定せずに発行者の JWKS を取得する

    `createRemoteJWKSet` は鍵をキャッシュし、まだ見たことのない `kid` を指定したトークンが来ると鍵セットを取得し直します。そのため、任意の鍵を受け入れることなく、ローテーションが自動的に反映されます。

    js
    import { createRemoteJWKSet, jwtVerify } from "jose";
    
    // Fetches the JWKS, caches it, and refetches when a token names an unknown kid
    // (at most once per cooldownDuration, 30 s by default).
    const jwks = createRemoteJWKSet(new URL("https://issuer.example.com/.well-known/jwks.json"));
    const { payload } = await jwtVerify(token, jwks, {
      algorithms: ["ES256"],
      issuer: "https://issuer.example.com",
    });
  3. 3.

    矛盾のないメタデータを付けて鍵を公開する

    発行者を自分で運用している場合は、各署名鍵に一意の `kid`、`use: "sig"`、その鍵で署名するトークンに合った `alg` と `crv` があることを確認してください。新しい鍵は、それで署名を始める前に公開してください。

    json
    {
      "keys": [
        { "kty": "EC", "crv": "P-256", "kid": "2026-10", "use": "sig", "alg": "ES256",
          "x": "…", "y": "…" }
      ]
    }

関連するエラー

署名エラーデータベースをすべて見る