Mensaje de error
invalid signature
Qué significa
El token se analizó sin problemas y su estructura es válida, pero la comprobación criptográfica falló: la firma sobre header.payload no se verifica con la clave proporcionada. O la clave no es la que firmó el token, o los bytes firmados cambiaron después de la firma.
Por qué ocurre
Verificación con la clave equivocada
frecuenteEs, con diferencia, el caso más frecuente: el entorno tiene una clave distinta de la que usó el emisor; por ejemplo, una clave pública obsoleta tras una rotación, una clave de preproducción frente a tokens de producción o un kid del JWKS que no coincide porque el verificador fija una clave mientras el emisor firma con otra.
Un firmante implementado a mano firmó los bytes equivocados
ocasionalEl código que construye tokens a mano debe firmar con SHA-256 los bytes ASCII de base64url(header).base64url(payload) y emitir el r‖s en bruto de 64 bytes que el RFC 7518 exige para ES256. Firmar el propio JSON, segmentos en base64 estándar o un resumen SHA-384 bajo un encabezado ES256 produce una firma bien formada que nunca se verifica. (Una firma codificada en DER se rechaza antes de la comprobación, con «"ES256" signatures must be "64" bytes», y un PEM estropeado por una variable de entorno ni siquiera se acepta como clave: falla con «secretOrPublicKey must be an asymmetric key when using ES256»).
El token se modificó después de firmarlo
ocasionalUn proxy, un componente de registro o un cliente volvió a serializar el JSON de la carga útil o cambió caracteres en él. Un solo carácter cambiado en el encabezado o en la carga útil invalida la firma: para eso precisamente se firma. (El relleno Base64 añadido a un segmento falla un paso antes, con «invalid token»; un token truncado falla con «jwt malformed» o con un error de longitud de la firma).
Cómo solucionarlo
- 1.
Calcular la huella de la clave en ambos lados
Calcula el hash de la clave pública que de verdad cargó el verificador y compáralo con el de la clave del emisor. Si las huellas difieren, la clave está obsoleta o es incorrecta —la causa más frecuente con diferencia— y la búsqueda termina en un solo paso.
js import { createHash, createPublicKey } from "node:crypto"; // Run on the verifier, and on the issuer with its signing key: the outputs must match. const spki = createPublicKey(process.env.JWT_PUBLIC_KEY).export({ type: "spki", format: "der" }); console.log(createHash("sha256").update(spki).digest("hex")); - 2.
Hacer coincidir el kid del token con la clave de verificación
Decodifica el encabezado sin verificar y compara su kid con la clave que tienes. Si el emisor publica un JWKS, resuelve la clave por kid en lugar de fijar una en el código.
js const { header } = jwt.decode(token, { complete: true }); console.log(header.kid, header.alg); // compare with your JWKS / configured key - 3.
Dejar que el depurador identifique la discrepancia
Pega el token y la clave pública en el depurador de JWT: verifica ES256/ES384/ES512 en local y distingue entre clave equivocada, carga útil manipulada y codificación de firma mal formada, en lugar de devolver un simple booleano.