本文へスキップ
ecdsa.com
jose (JavaScript)JWT ライブラリ

エラーメッセージ

signature verification failed

jose (JavaScript) — JWSSignatureVerificationFailed, code ERR_JWS_SIGNATURE_VERIFICATION_FAILED

このエラーの意味

jose は JWS を正常に解析し、暗号学的なチェックを実行しましたが、選択した鍵では署名を検証できませんでした。構造、アルゴリズム、鍵の種類はいずれも問題ありませんでした。数学的に一致しなかっただけであり、原因は鍵か、署名対象のバイト列の改変にあると考えられます。

発生する理由

修正方法

  1. 1.

    kid をもとに発行者の JWKS から鍵を取得する

    1 つの鍵を手動で固定するのではなく、トークンごとに正しい鍵を jose に選ばせてください。createRemoteJWKSet は鍵をキャッシュし、ローテーションのたびに更新します。

    js
    import { createRemoteJWKSet, jwtVerify } from "jose";
    
    const jwks = createRemoteJWKSet(new URL("https://issuer.example/.well-known/jwks.json"));
    const { payload } = await jwtVerify(token, jwks, {
      algorithms: ["ES256"],
      issuer: "https://issuer.example",
    });
  2. 2.

    node:crypto で署名する場合は生の r‖s を出力する

    独自の署名処理では IEEE P1363 形式の出力を指定し、署名が JWS の要求する 64 バイトの形式になるようにしてください。あるいは、3 番目のセグメントの長さを調べて、署名処理が出力したものを確認してください。

    js
    import { sign } from "node:crypto";
    
    const sig = sign("sha256", Buffer.from(signingInput), {
      key: privateKey,
      dsaEncoding: "ieee-p1363", // raw r||s, 64 bytes for P-256
    });
  3. 3.

    署名セグメントの形を確認する

    トークンの 3 番目のセグメントをデコードしてください。64 バイトなら生の r‖s(ES256 として正しい形式)、0x30 で始まる約 70 バイトなら DER です。下にある DER と生の形式の変換ツールは、r と s の値を表示し、2 つの形式を相互に変換します。

関連するエラー

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