本文へスキップ
ecdsa.com
JJWT (Java)Java

エラーメッセージ

JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

別の表記

  • io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

JJWT (Java) — io.jsonwebtoken.security.SignatureException from JwtParser.parseSignedClaims

このエラーの意味

JJWT は、設定された鍵を使って、トークンのヘッダーとペイロードに対する署名を再計算(HMAC)または検証(RSA、ECDSA、EdDSA)しましたが、トークンの署名セグメントと一致しませんでした。トークンの解析には問題がなく、アルゴリズムも鍵に適合しています。単に鍵とトークンが対応していないか、署名後にトークンが変更されています。

発生する理由

修正方法

  1. 1.

    鍵ロケーターで kid から鍵を解決する

    JJWT 0.12 以降は `keyLocator` に対応しています。これはヘッダーを受け取り、適切な鍵を返します。ローテーションのたびに更新する JWKS と組み合わせてください。

    java
    import io.jsonwebtoken.*;
    import java.security.Key;
    
    // Pick the verification key by the token's kid instead of a single static key.
    Locator<Key> keys = new LocatorAdapter<>() {
      @Override
      protected Key locate(JwsHeader header) {
        Key key = publicKeysByKid.get(header.getKeyId()); // refreshed from the issuer's JWKS
        if (key == null) throw new UnsupportedJwtException("unknown kid " + header.getKeyId());
        return key;
      }
    };
    Jws<Claims> jws = Jwts.parser().keyLocator(keys).requireIssuer("https://issuer.example.com/").build().parseSignedClaims(token);
  2. 2.

    HMAC 鍵のバイト列を揃える

    設定されたシークレットがテキストなのか base64 なのかを決め、すべての側で同じ方法で鍵を導出してください。HMAC 計算ツールでは、両方の解釈での MAC を確認できます。

    java
    // Both sides must derive the same key bytes. If the secret is stored base64-encoded, decode it.
    javax.crypto.SecretKey key = io.jsonwebtoken.security.Keys.hmacShaKeyFor(
        java.util.Base64.getDecoder().decode(System.getenv("JWT_SECRET_B64")));

関連するエラー

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