Saltar al contenido
ecdsa.com
jose (JavaScript)Bibliotecas de JWT

Mensaje de error

signature verification failed

jose (JavaScript) — JWSSignatureVerificationFailed, code ERR_JWS_SIGNATURE_VERIFICATION_FAILED

Qué significa

jose analizó el JWS correctamente y ejecutó la comprobación criptográfica, pero la firma no se verifica con la clave que seleccionó. La estructura, el algoritmo y el tipo de clave eran aceptables: simplemente, las matemáticas no cuadraron, lo que apunta a la clave o a bytes firmados alterados.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Resolver las claves por kid desde el JWKS del emisor

    Deja que jose elija la clave correcta para cada token en lugar de recurrir a la fijación manual de una sola clave; createRemoteJWKSet guarda las claves en caché y las actualiza a lo largo de las rotaciones.

    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.

    Emitir r‖s en bruto si firmas con node:crypto

    En los firmantes personalizados, solicita la salida IEEE P1363 para que la firma tenga el formato de 64 bytes que exige JWS, o verifica lo que produjo tu firmante comprobando la longitud del tercer segmento.

    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.

    Comprobar la forma del segmento de firma

    Decodifica el tercer segmento del token: 64 bytes significa r‖s en bruto (lo correcto para ES256); unos 70 bytes que empiezan por 0x30 significa DER. El conversor DER ⇄ raw de abajo muestra los valores de r y s y convierte entre los dos formatos.

Errores relacionados

Explorar toda la base de datos de errores de firma