Zum Inhalt springen
ecdsa.com
Node.js

jsonwebtoken (Node.js)

jsonwebtoken von Auth0, das meistinstallierte JWT-Paket für Node.js: HMAC-, RSA- und ECDSA-Tokens auf Basis von node:crypto, seit Version 9 mit Algorithmusprüfungen, die an den Schlüsseltyp gebunden sind – aber ohne EdDSA.
Lizenz
MIT
Geprüfte Version
9.0.3 ·
Quellcode
github.com/auth0/node-jsonwebtoken
Dokumentation
github.com/auth0/node-jsonwebtoken#readme

Kompatibilität auf einen Blick

JOSE und JWT

JWS-Algorithmen
HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512

jsonwebtoken signiert und prüft JSON Web Tokens mit drei Aufrufen: jwt.sign(), jwt.verify() und jwt.decode(). Die JWS-Schicht übernehmen die Pakete jws und jwa, die Kryptografie erledigt node:crypto, Schlüssel können also PEM-Strings, Buffer oder Instanzen von KeyObject sein. jwt.decode() parst das Token nur – die Methode prüft nie die Signatur, und Code, der Claims daraus liest, vertraut allem, was der Absender hineingeschrieben hat.

Version 9 hat die klassischen Wege zur Algorithm Confusion geschlossen, und die Prüfung bestätigte das für 9.0.3: Ohne die Option algorithms ergibt sich die Liste der zulässigen Algorithmen aus dem Schlüsseltyp, ein HS256-Token mit dem Text eines öffentlichen Schlüssels als HMAC-Schlüssel wird abgelehnt, und alg: none kommt nur durch, wenn du none aufführst und überhaupt keinen Schlüssel angibst. Übergib algorithms trotzdem – die Option dokumentiert die Erwartung und greift weiter, falls sich der Schlüsseltyp einmal ändert.

Die Algorithmusliste endet beim Umfang von RFC 7518: Es gibt kein EdDSA, Ed25519 oder ES256K. Ein Token von einem Aussteller, der mit Ed25519 signiert – verbreitet bei jose sowie in Go- und Rust-Stacks –, lässt sich hier nicht prüfen; nimm stattdessen jose. ES256 verlangt außerdem einen P-256-Schlüssel, und das Signieren mit einem P-384-Schlüssel unter diesem Namen wirft eine Exception, statt ein Token zu erzeugen, das andere Bibliotheken ablehnen würden.

ECDSA-Signaturen im Token haben die 64 Byte lange rohe Form r‖s, die JWS vorschreibt. Wurde ein Token von Hand aus openssl dgst, SHA256withECDSA aus Java oder einem Cloud-KMS zusammengesetzt, ist seine Signatur DER-kodiert, und die Prüfung scheitert mit "ES256" signatures must be "64" bytes – füge das Token in den JWT-Debugger ein, um die Länge der Signatur zu sehen, und korrigiere die Signatur mit dem Konverter DER ⇄ Raw.

Zwei Standardeinstellungen überraschen viele Teams – die eine ist strenger, die andere lockerer als angenommen: clockTolerance ist null, sodass schon wenige Sekunden Uhrenabweichung zwischen Servern zu jwt expired führen, und exp ist optional, sodass ein ohne diesen Claim ausgestelltes Token nie abläuft. Setze beim Signieren expiresIn und beim Prüfen maxAge oder verlange exp ausdrücklich; prüfe HMAC-Secrets mit dem JWT-Secret-Checker.

Fakten und die Prüfungen dahinter

Nichts im Folgenden ist aus einer Dokumentation abgeschrieben. Das Prüfskript content/libraries/verify/jsonwebtoken/run.sh hat jsonwebtoken (Node.js) 9.0.3 unter Node.js 24.22.0 am 20. Oktober 2026 im Container-Image node:24.22.0-bookworm-slim ausgeführt; die Seite muss mit seiner Ausgabe übereinstimmen, und jeder Fakt führt die zugehörigen Zeilen auf.

  • JWS-Algorithmen

    HS256HS384HS512RS256RS384RS512PS256PS384PS512ES256ES384ES512

    In der Prüfung funktionierten Signieren und Prüfen mit HS256/384/512, RS256/384/512, PS256/384/512 und ES256/384/512. EdDSA, Ed25519, Ed448, ES256K und ML-DSA wurden beim Signieren abgelehnt.

    Von der Prüfung aufgezeichnet
    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
  • Kodierung von ES256-Signaturen

    raw

    ES256-Signaturen im Token bestehen aus 64 Byte rohem r‖s, wie RFC 7518 es verlangt; die Bibliothek wandelt das DER um, das node:crypto erzeugt.

    Von der Prüfung aufgezeichnet
    fact jws-ecdsa-encoding = raw
  • DER-Signatur in einer JWS

    rejected

    Ein Token, dessen ES256-Signatur in DER umkodiert wurde, scheitert mit "ES256" signatures must be "64" bytes, saw "72" (die Zahl ist die Länge des DER-Blobs).

    Von der Prüfung aufgezeichnet
    fact jws-der-signature = rejected
    evidence jws-der-signature: TypeError: "ES256" signatures must be "64" bytes, saw "72"
  • Allowlist der Algorithmen

    from-key

    Ohne algorithms lässt die Prüfung nur die Algorithmen zu, die zum Schlüssel passen: Ein HS256-Token bestand die Prüfung mit einem gemeinsamen Geheimnis, ein ES256-Token mit einem öffentlichen Schlüssel vom Typ EC, und ein RS256-Token scheiterte an einem EC-Schlüssel mit invalid algorithm.

    Von der Prüfung aufgezeichnet
    fact jwt-algorithm-allowlist = from-key
    evidence jwt-algorithm-allowlist: RS256 token against an EC key: JsonWebTokenError: invalid algorithm
  • Unsignierte Tokens (alg none)

    opt-in

    Ein unsigniertes Token wird mit jwt signature is required abgelehnt, sobald ein Schlüssel übergeben wird; es besteht die Prüfung nur, wenn algorithms den Wert none enthält und das Schlüsselargument leer ist.

    Von der Prüfung aufgezeichnet
    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
  • Öffentlicher Schlüssel als HMAC-Secret

    rejected

    Ein HS256-Token, dessen HMAC-Schlüssel der PEM-Text des öffentlichen Schlüssels ist, wurde sowohl ohne Algorithmusliste (invalid algorithm) als auch mit algorithms: ["HS256"] (secretOrPublicKey must be a symmetric key when using HS256) abgelehnt.

    Von der Prüfung aufgezeichnet
    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
  • Abgleich der Kurve mit alg

    enforced

    Das Signieren mit ES256 und einem P-384-Schlüssel wirft "alg" parameter "ES256" requires curve "prime256v1". – ES256, ES384 und ES512 sind an P-256, P-384 und P-521 gebunden.

    Von der Prüfung aufgezeichnet
    fact jwt-ecdsa-curve-check = enforced
    evidence jwt-ecdsa-curve-check: Error: "alg" parameter "ES256" requires curve "prime256v1".
  • Standardtoleranz für Uhrabweichungen

    0s

    Standardmäßig keine Toleranz (Leeway): Ein Token, das drei Sekunden zuvor abgelaufen war, wurde abgelehnt. Setze clockTolerance in Sekunden, um Uhrenabweichungen zuzulassen.

    Von der Prüfung aufgezeichnet
    fact jwt-clock-skew = 0s
  • Ablauf-Claim erforderlich

    no

    Ein Token ohne den Claim exp bestand die Prüfung; der Ablauf wird nur durchgesetzt, wenn der Claim vorhanden oder maxAge gesetzt ist.

    Von der Prüfung aufgezeichnet
    fact jwt-exp-required = no

Verwendung

Stelle ein ES256-Token aus und prüfe es, wobei die prüfende Seite Algorithmus, Aussteller und Audience festlegt.
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);

Die Snippet-Testumgebung führt jedes Beispiel unverändert im Container-Image node:24.22.0-bookworm-slim aus, und der Lauf schlägt fehl, wenn die Ausgabe nicht übereinstimmt.

Einrichtung
npm init -y >/dev/null && npm install --no-audit --no-fund jsonwebtoken@9.0.3
Befehl
node usage.mjs
Ausgabe muss passen (regulärer Ausdruck)
sub: user-42

Bibliotheken