Saltar al contenido
ecdsa.com
Node.js

jsonwebtoken (Node.js)

jsonwebtoken de Auth0, el paquete JWT más instalado para Node.js: tokens HMAC, RSA y ECDSA sobre node:crypto, con comprobaciones de algoritmo ligadas al tipo de clave desde la versión 9, pero sin EdDSA.
Licencia
MIT
Versión comprobada
9.0.3 ·
Código fuente
github.com/auth0/node-jsonwebtoken
Documentación
github.com/auth0/node-jsonwebtoken#readme

Compatibilidad de un vistazo

JOSE y JWT

Algoritmos JWS
HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512

jsonwebtoken firma y verifica JSON Web Tokens con tres llamadas: jwt.sign(), jwt.verify() y jwt.decode(). Gestiona la capa JWS mediante los paquetes jws y jwa y hace la criptografía con node:crypto, así que las claves pueden ser cadenas PEM, buffers o instancias KeyObject. jwt.decode() solo analiza el token —nunca comprueba la firma—, y el código que lee los claims de su resultado se fía de lo que haya escrito el remitente.

La versión 9 cerró las vías clásicas de confusión de algoritmos, y la comprobación lo confirmó con la 9.0.3: sin la opción algorithms, la lista de algoritmos permitidos se deriva del tipo de clave, un token HS256 con el texto de una clave pública como clave se rechaza y alg: none solo pasa cuando incluyes none en la lista y no proporcionas ninguna clave. Pasa algorithms de todos modos: documenta el contrato y sigue funcionando si el tipo de clave cambia algún día.

La lista de algoritmos se queda en el conjunto del RFC 7518: no hay EdDSA, Ed25519 ni ES256K. Un token de un emisor que firma con Ed25519 —algo habitual con jose y con stacks de Go y Rust— no se puede verificar aquí; usa jose en su lugar. ES256 también exige una clave P-256, y firmar bajo ese nombre con una clave P-384 lanza un error en lugar de producir un token que otras bibliotecas rechazarían.

Las firmas ECDSA dentro del token tienen la forma r‖s en bruto de 64 bytes que exige JWS. Cuando un token se arma a mano con openssl dgst, con SHA256withECDSA de Java o con un KMS en la nube, su firma es DER y la verificación falla con "ES256" signatures must be "64" bytes: pega el token en el decodificador de JWT para ver la longitud de la firma y corrígela con el conversor DER ⇄ en bruto.

Dos valores predeterminados sorprenden a muchos equipos, uno por más estricto y otro por más laxo de lo que suponen: clockTolerance es cero, así que unos pocos segundos de desfase de reloj entre servidores ya producen jwt expired, y exp es opcional, así que un token emitido sin él nunca caduca. Configura expiresIn al firmar y maxAge o un requisito explícito de exp al verificar; comprueba los secretos HMAC con el comprobador de secretos JWT.

Datos y las comprobaciones que los respaldan

Nada de lo que sigue está copiado de la documentación. La comprobación content/libraries/verify/jsonwebtoken/run.sh ejecutó jsonwebtoken (Node.js) 9.0.3 en Node.js 24.22.0 en la imagen de contenedor node:24.22.0-bookworm-slim el 20 de octubre de 2026; la página debe coincidir con lo que imprimió, y cada dato cita esas líneas.

  • Algoritmos JWS

    HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512

    Con HS256/384/512, RS256/384/512, PS256/384/512 y ES256/384/512 se firmó y se verificó en la comprobación. EdDSA, Ed25519, Ed448, ES256K y ML-DSA se rechazaron al firmar.

    Registrado por la comprobación
    fact jws-algorithms = HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512
    evidence jws-algorithms: ES256K: sign throws Error: "algorithm" must be a valid string enum value
    evidence jws-algorithms: EdDSA: sign throws Error: "algorithm" must be a valid string enum value
    evidence jws-algorithms: Ed25519: sign throws Error: "algorithm" must be a valid string enum value
    evidence jws-algorithms: Ed448: sign throws Error: "algorithm" must be a valid string enum value
    evidence jws-algorithms: ML-DSA-44: sign throws Error: "algorithm" must be a valid string enum value
  • Codificación de la firma ES256

    raw

    Las firmas ES256 del token son 64 bytes de r‖s en bruto, como exige el RFC 7518; la biblioteca las convierte desde el DER que produce node:crypto.

    Registrado por la comprobación
    fact jws-ecdsa-encoding = raw
  • Firma DER dentro de un JWS

    rejected

    Un token cuya firma ES256 se volvió a codificar en DER falla con "ES256" signatures must be "64" bytes, saw "72" (el número es la longitud del blob DER).

    Registrado por la comprobación
    fact jws-der-signature = rejected
    evidence jws-der-signature: TypeError: "ES256" signatures must be "64" bytes, saw "72"
  • Lista de algoritmos permitidos

    from-key

    Sin algorithms, la verificación solo permite los algoritmos que encajan con la clave: un token HS256 se verificó con un secreto compartido y un token ES256 con una clave pública EC, mientras que un token RS256 contra una clave EC falló con invalid algorithm.

    Registrado por la comprobación
    fact jwt-algorithm-allowlist = from-key
    evidence jwt-algorithm-allowlist: RS256 token against an EC key: JsonWebTokenError: invalid algorithm
  • Tokens sin firma (alg none)

    opt-in

    Un token sin firmar se rechaza con jwt signature is required siempre que se proporciona una clave; solo se verifica cuando algorithms contiene none y el argumento de la clave está vacío.

    Registrado por la comprobación
    fact jwt-alg-none = opt-in
    evidence jwt-alg-none: with a key: JsonWebTokenError: jwt signature is required
    evidence jwt-alg-none: algorithms ["none"] and no key: verified
  • Clave pública usada como secreto HMAC

    rejected

    Un token HS256 cuya clave HMAC es el texto PEM de la clave pública se rechazó tanto sin lista de algoritmos (invalid algorithm) como con algorithms: ["HS256"] (secretOrPublicKey must be a symmetric key when using HS256).

    Registrado por la comprobación
    fact jwt-hmac-public-key = rejected
    evidence jwt-hmac-public-key: no list: JsonWebTokenError: invalid algorithm
    evidence jwt-hmac-public-key: algorithms ["HS256"]: JsonWebTokenError: secretOrPublicKey must be a symmetric key when using HS256
  • Curva cotejada con alg

    enforced

    Firmar ES256 con una clave P-384 lanza "alg" parameter "ES256" requires curve "prime256v1".: ES256, ES384 y ES512 están ligados a P-256, P-384 y P-521.

    Registrado por la comprobación
    fact jwt-ecdsa-curve-check = enforced
    evidence jwt-ecdsa-curve-check: Error: "alg" parameter "ES256" requires curve "prime256v1".
  • Desfase de reloj predeterminado

    0s

    Sin tolerancia por defecto: se rechazó un token que había caducado 3 segundos antes. Configura clockTolerance en segundos para admitir el desfase de reloj.

    Registrado por la comprobación
    fact jwt-clock-skew = 0s
  • Claim de caducidad obligatorio

    no

    Un token sin el claim exp se verificó correctamente; la caducidad solo se aplica cuando el claim está presente o se configura maxAge.

    Registrado por la comprobación
    fact jwt-exp-required = no

Uso

Emite y verifica un token ES256, con el algoritmo, el emisor y la audiencia fijados en el lado de la verificación.
import { generateKeyPairSync } from "node:crypto";
import jwt from "jsonwebtoken";

const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });

const token = jwt.sign({ sub: "user-42" }, privateKey, {
  algorithm: "ES256",
  expiresIn: "10m",
  issuer: "https://auth.example.com",
  audience: "api",
});

// Pin the algorithm, issuer and audience instead of trusting the token header.
const claims = jwt.verify(token, publicKey, {
  algorithms: ["ES256"],
  issuer: "https://auth.example.com",
  audience: "api",
});

console.log("sub:", claims.sub);

El arnés de pruebas de fragmentos de código ejecuta cada ejemplo tal cual en la imagen de contenedor node:24.22.0-bookworm-slim, y la ejecución falla si la salida no coincide.

Configuración
npm init -y >/dev/null && npm install --no-audit --no-fund jsonwebtoken@9.0.3
Comando
node usage.mjs
La salida debe coincidir (expresión regular)
sub: user-42

Bibliotecas