Saltar al contenido
ecdsa.com
JJWT (Java)Java

Mensaje de error

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

También se muestra como

  • 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

Qué significa

JJWT volvió a calcular (HMAC) o verificó (RSA, ECDSA, EdDSA) la firma sobre el encabezado y la carga útil del token con la clave configurada, y no coincidió con el segmento de firma del token. El token se analizó bien y el algoritmo encajaba con la clave; simplemente la clave y el token no van juntos, o el token cambió después de firmarse.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Resolver las claves por kid con un localizador de claves

    JJWT 0.12+ admite `keyLocator`, que recibe el encabezado y devuelve la clave correcta. Combínalo con un JWKS que actualices en cada rotación.

    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.

    Acordar los bytes de la clave HMAC

    Decide si el secreto configurado es texto o base64 y deriva la clave de la misma forma en todos los lados. La calculadora HMAC muestra el MAC con ambas interpretaciones.

    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")));

Errores relacionados

Explorar toda la base de datos de errores de firma