Die Signatur eines JSON Web Tokens (JWT) prüfen

prüft die Signatur eines JWT (HS256, HS384, HS512, RS256, RS384, RS512) anhand eines Secrets oder eines öffentlichen Schlüssels und inspiziert die Claims
Für HS256 / HS384 / HS512: der geteilte geheime String. Für RS256 / RS384 / RS512: der öffentliche Schlüssel im PEM-Format.

Warum die Signatur eines JWT überprüfen?

Ein JSON Web Token (JWT) zerlegt sich in drei durch Punkte getrennte Teile: header.payload.signature. Ein JWT zu dekodieren bedeutet einfach, die ersten beiden Teile zu lesen (die in Base64URL kodiert sind). Jeder kann das tun, und jeder kann ein JWT mit dem Payload seiner Wahl bauen. Was ein JWT vertrauenswürdig macht, ist ausschließlich die Signatur: Ein JWT ohne Überprüfung zu akzeptieren bedeutet, jeden in Ihr Haus zu lassen, der vorgibt, jemand zu sein, ohne nach einem Ausweis zu fragen.

Dieses Tool überprüft die Signatur eines JWT anhand eines Schlüssels. Es begnügt sich nicht mit Dekodieren: Es berechnet die Signatur aus Header, Payload und Ihrem Schlüssel neu und vergleicht sie dann mit der Signatur des Tokens. Wenn beide übereinstimmen, ist das Token authentisch. Andernfalls wurde es gefälscht, verändert oder mit einem anderen Schlüssel signiert.

Die Überprüfung ist der Eckpfeiler jeder Architektur, die JWTs zur Authentifizierung oder Autorisierung verwendet: ohne gültige Signatur kann das Payload lügen. Ein Angreifer, der "role":"user" in "role":"admin" ändert, hätte keinerlei Schwierigkeit damit, wenn der Server nur das Tokenformat und nicht seine Signatur überprüft.

Gängige Algorithmen

Die JWT-Spezifikation (RFC 7518, JSON Web Algorithms) definiert mehrere Algorithmenfamilien. Hier sind die in der Produktion am häufigsten verwendeten:

  • HMAC (HS256, HS384, HS512): symmetrische Signatur auf HMAC-SHA-Basis. Der gleiche geheime Schlüssel dient zum Signieren und Überprüfen. Einfach einzurichten, performant, aber jede Partei, die das Token überprüfen kann, kann auch eines ausstellen. Geeignet für Szenarien, in denen Aussteller und Überprüfer dasselbe Team oder derselbe Dienst sind.
  • RSA (RS256, RS384, RS512): asymmetrische Signatur. Der private Schlüssel signiert, der öffentliche Schlüssel überprüft. Ideal, wenn Aussteller und Überprüfer unterschiedliche Entitäten sind (OAuth2, OpenID Connect, Identitätsföderation). Es ist der von den meisten öffentlichen Identity Providern bevorzugte Algorithmus.
  • ECDSA (ES256, ES384): asymmetrische Signatur auf elliptischen Kurven. Gleiche Logik wie RSA (privater Schlüssel zum Signieren, öffentlicher zum Überprüfen), aber mit kompakteren Schlüsseln und Signaturen bei gleichem Sicherheitsniveau. In modernen Architekturen zunehmend verbreitet.

So stellen Sie den Schlüssel bereit

Das erwartete Schlüsselformat hängt vom im JWT-Header deklarierten Algorithmus ab:

  • HS256, HS384, HS512: Der Schlüssel ist eine geheime Zeichenkette (string). Das ist das mit dem Aussteller geteilte Secret, oft in einer Umgebungsvariablen wie JWT_SECRET gespeichert. Keine besondere Formatierung, nur der rohe Wert.
  • RS256, RS384, RS512: Der Schlüssel ist ein öffentlicher RSA-Schlüssel im PEM-Format, der mit -----BEGIN PUBLIC KEY----- beginnt und mit -----END PUBLIC KEY----- endet. Bewahren Sie die Zeilenumbrüche unverändert auf, sonst weigert sich OpenSSL, ihn zu parsen.
  • ES256, ES384: Der Schlüssel ist ein öffentlicher ECDSA-Schlüssel im PEM-Format, auf der entsprechenden Kurve (P-256 für ES256, P-384 für ES384).

Beispiel eines erwarteten öffentlichen RSA-Schlüssels

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxe...
...vQIDAQAB
-----END PUBLIC KEY-----

Wie funktioniert die Überprüfung?

Unser Server reproduziert genau die Operation, die der Aussteller durchgeführt hat:

  1. Er teilt das JWT in Header, Payload und Signatur.
  2. Er verkettet base64url(header) + "." + base64url(payload).
  3. Für HMAC berechnet er einen HMAC-SHA-256/384/512 mit Ihrem geheimen Schlüssel und vergleicht ihn dann mit der empfangenen Signatur über hash_equals (zeitkonstanter Vergleich zur Vermeidung von zeitbasierten Angriffen).
  4. Für RSA ruft er openssl_verify mit Ihrem öffentlichen Schlüssel im PEM-Format auf.

Anwendungsfälle

  • API-Authentifizierungs-Debugging: Sie erhalten einen 401, prüfen Sie, ob Ihr Token tatsächlich mit dem erwarteten Schlüssel signiert ist.
  • Validierung eines von einem Anbieter erhaltenen Tokens: Ein Partner (Auth0, Keycloak, Cognito, Okta) sendet Ihnen in RS256 signierte JWTs; Sie möchten mit seinem öffentlichen Schlüssel bestätigen, dass sie tatsächlich von ihm stammen.
  • Sicherheitsaudit: prüfen, dass ein Drittanbieterdienst seine Tokens korrekt mit einem robusten Algorithmus signiert, und nicht in HS256 mit einem schwachen Secret.
  • Manuelle Tests: prüfen, dass ein von Ihrem Code erzeugtes JWT die Überprüfung mit dem bereitgestellten öffentlichen Schlüssel besteht.
  • Schnellprüfung eines empfangenen Tokens: während der Integration eines SSO oder einer Partner-API in wenigen Sekunden überprüfen, dass die Signatur-/Schlüsselkette funktioniert, bevor man auch nur eine Zeile Code schreibt.

So verwenden Sie das Tool

  1. Fügen Sie das vollständige JWT ein (die drei durch Punkte getrennten Teile).
  2. Geben Sie den zum Header-Algorithmus passenden Schlüssel an:
    • Für HS256, HS384 oder HS512 ist der Schlüssel die mit dem Aussteller geteilte geheime Zeichenkette. Es ist eine freie Zeichenkette, oft in einer Umgebungsvariablen wie JWT_SECRET gespeichert.
    • Für RS256, RS384 oder RS512 ist der Schlüssel der öffentliche Schlüssel im PEM-Format, der mit -----BEGIN PUBLIC KEY----- beginnt und mit -----END PUBLIC KEY----- endet.
  3. Starten Sie die Überprüfung. Das Tool zeigt den Status (gültig oder ungültig) und das dekodierte Payload an.

Häufige zu vermeidende Stolperfallen

  • Algorithmus "none": Die Spec erlaubt alg: none, was "keine Signatur" bedeutet. Eine klassische Schwachstelle besteht darin, ein Token mit diesem Header zu bauen in der Hoffnung, dass der Server es akzeptiert. Unser Tool lehnt Tokens mit alg: none systematisch ab.
  • HMAC-vs.-RSA-Verwechslung (algorithm confusion): Ein Angreifer ändert den Algorithmus RS256 in HS256 und signiert das Payload mit dem als HMAC-Secret verwendeten öffentlichen RSA-Schlüssel. Wenn der Server den Algorithmus nicht kontrolliert, akzeptiert er das Token. Sperren Sie den erwarteten Algorithmus immer serverseitig.
  • HMAC-Secrets fest im Code: Ein in einem Git-Repository commitetes Secret macht das gesamte Vertrauen in die Tokens zunichte. Speichern Sie Secrets in Umgebungsvariablen oder einem Anwendungs-Vault.
  • Öffentlicher vs. privater Schlüssel: Um ein in RSA oder ECDSA signiertes JWT zu überprüfen, stellt man den öffentlichen Schlüssel bereit, niemals den privaten. Der private dient nur zum Signieren und darf niemals den Aussteller verlassen.
  • Ignorierter Ablauf: Eine gültige Signatur auf einem abgelaufenen Token darf niemals akzeptiert werden. Denken Sie daran, exp und nbf zu überprüfen.
  • Nicht kontrollierte Audience: Ein für die API A bestimmtes Token sollte nicht von der API B akzeptiert werden. Prüfen Sie den Claim aud.

Zeitliche Claims: exp und nbf

Über die Signatur hinaus muss ein gültiges JWT auch seine zeitlichen Einschränkungen einhalten:

  • exp (expiration): Das Token ist nach diesem Datum nicht mehr gültig.
  • nbf (not before): Das Token ist vor diesem Datum noch nicht gültig.

Unser Tool signalisiert explizit, wenn ein Token abgelaufen oder noch nicht gültig ist, selbst wenn seine Signatur korrekt ist. Das ist wichtig: Eine gültige Signatur auf einem abgelaufenen Token darf in der Produktion niemals akzeptiert werden.

Unterschied zu unserem JWT-Decoder

Unser JWT-Decoder begnügt sich damit, die Header- und Payload-Teile zu dekodieren, um sie lesbar zu machen. Er führt keine Signaturüberprüfung durch und verlangt keinen Schlüssel. Verwenden Sie ihn, um den Inhalt eines Tokens schnell zu inspizieren. Verwenden Sie den JWT-Verifier (diese Seite), sobald Sie beweisen müssen, dass ein Token authentisch ist. Um zu Testzwecken ein signiertes JWT zu bauen, verwenden Sie unseren JWT-Builder.

Häufig gestellte Fragen

Warum RS256 statt HS256?

Mit HS256 teilen sich Aussteller und Überprüfer dasselbe Secret: Jeder Überprüfer kann also Tokens ausstellen. Das ist handhabbar, wenn man beide Enden kontrolliert. Sobald es um einen einzigen Identity Provider mit mehreren Konsumentendiensten geht, wechselt man zu RS256: Der Aussteller behält den privaten Schlüssel, der öffentliche Schlüssel wird an alle APIs verteilt, die überprüfen müssen. Keine Konsumenten-API kann dann Tokens schmieden.

Wie holt man sich den öffentlichen Schlüssel eines Identity Providers (IdP)?

Die meisten IdPs stellen einen standardisierten JWKS-Endpoint bereit (zum Beispiel https://exemple.com/.well-known/jwks.json). Dieser Endpoint gibt ein JSON zurück, das die aktiven öffentlichen Schlüssel enthält. Sie können den JWK-Eintrag, der dem kid des Headers Ihres JWT entspricht, über den Befehl openssl oder über eine JWKS-Bibliothek Ihres Stacks (zum Beispiel jose-jwt, jwks-rsa) in einen PEM-Schlüssel konvertieren.

Was tun, wenn der Verify fehlschlägt?

Prüfen Sie zuerst den Algorithmus: Ein in HS256 signiertes Token wird nicht mit einem RSA-Schlüssel überprüft, und umgekehrt. Prüfen Sie dann den Schlüssel: Ein überzähliges Leerzeichen, ein fehlender Zeilenumbruch in einem PEM-Schlüssel oder ein leicht abweichendes HMAC-Secret von dem, das der Aussteller verwendet hat, reichen aus, um die Überprüfung scheitern zu lassen. Wenn der IdP eine Schlüsselrotation durchgeführt hat, kann Ihr kid auf einen Schlüssel zeigen, den Sie nicht mehr haben.

JWKS, was ist das?

JWKS (JSON Web Key Set, RFC 7517) ist ein JSON-Format, das eine Menge öffentlicher Schlüssel beschreibt. Jeder Schlüssel wird durch eine kid (key ID) identifiziert, und das zu überprüfende JWT referenziert diese kid in seinem Header. Der Mechanismus erlaubt es dem IdP, seine Schlüssel zu rotieren, ohne die Überprüfer zu zerstören: Sie befragen einfach den JWKS-Endpoint, um den zum kid des empfangenen Tokens passenden Schlüssel abzurufen.

Wie erzeugt man ein RSA-Schlüsselpaar zum Signieren meiner JWTs?

Mit OpenSSL: openssl genrsa -out private.pem 2048, dann openssl rsa -in private.pem -pubout -out public.pem. Der private Schlüssel signiert beim Aussteller, der öffentliche Schlüssel überprüft beim Konsumenten. Für neue Dienste bevorzugen Sie 3072 oder 4096 Bit.

Sollte man das JWT zusätzlich zum Signieren verschlüsseln (JWE)?

Ein signiertes JWT (JWS) garantiert Integrität und Authentizität, aber das Payload bleibt für jeden lesbar, der es abruft. Wenn das Token sensible Daten enthält (interne Bezeichner, detaillierte Rechte, personenbezogene Daten), erwägen Sie das JWE-Format (JSON Web Encryption), das das Payload zusätzlich zum Signieren verschlüsselt.

Beispielanfrage

curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
  -H "Content-Type: application/json" \
  -d '{"token":"...","key":"..."}'

Eingabeschema

Feld Typ Erforderlich Standard
token text
key text

Endpunkte

  • GET https://cdrn.fr/api/v1/tools - listet alle verfügbaren Tools auf
  • GET https://cdrn.fr/api/v1/tools/jwt-verifier - liefert das Schema dieses Tools
  • POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute - führt dieses Tool mit einem JSON-Payload aus