JWT Decoder

Füge einen JWT ein und sieh sofort Header, Payload und Signatur.

..
{{ __t('section_header') }}

                        
{{ __t('section_payload') }}


                            
{{ __t('claims_heading') }}
{{ __t('section_signature') }}

                            

{{ __t('signature_note') }}

{{ __t('empty_state') }}

Was ist ein JWT?

JSON Web Token (JWT, RFC 7519) ist ein offener Standard, um Ansprüche (Claims) zwischen zwei Parteien sicher und kompakt zu übertragen. JWTs werden in modernen Web-APIs für Authentifizierung und Autorisierung eingesetzt — etwa nach einem Login zur Identifikation des Nutzers bei jeder folgenden Anfrage.

Wichtig: Ein JWT ist nicht verschlüsselt, sondern nur signiert. Jeder, der den Token besitzt, kann seinen Inhalt lesen. Speichere also keine Passwörter oder sensiblen Daten im Payload.

Aufbau eines JWT

  • Header — beschreibt den Token-Typ (typ) und den verwendeten Signatur-Algorithmus (alg), z. B. HS256, RS256.
  • Payload — enthält die Claims (Datenpunkte) als JSON, base64url-codiert. Standard- und Custom-Claims sind möglich.
  • Signatur — kryptografische Signatur über Header + Payload, mit dem in alg angegebenen Algorithmus erzeugt.

Standard-Claims (RFC 7519)

  • iss — Issuer (Aussteller des Tokens)
  • sub — Subject (typischerweise die User-ID)
  • aud — Audience (für wen der Token bestimmt ist)
  • exp — Expiration Time (Ablaufzeitpunkt als Unix-Timestamp)
  • iat — Issued At (Ausstellungszeitpunkt)
  • nbf — Not Before (gültig nicht vor diesem Zeitpunkt)

Ist dieses Tool sicher?

Ja. Die Decodierung erfolgt vollständig in deinem Browser mit JavaScript. Es wird kein Token an einen Server gesendet, und nichts wird protokolliert. Du kannst die Implementierung jederzeit in den Browser-Entwicklertools überprüfen. Trotzdem solltest du produktiv genutzte Tokens nur in vertrauenswürdigen Umgebungen einfügen.

Wie ein JWT validiert wird

Ein JSON Web Token ist nach RFC 7519 definiert als kompakte URL-safe Repraesentation von Claims. Die drei Teile header.payload.signature sind jeweils Base64URL-kodiert (RFC 4648 §5) — keine klassische Base64 mit + und /, sondern - und _, und ohne Padding-Gleichheitszeichen am Ende. Decoding heisst also: String an Punkten splitten, jeden Teil Base64URL-dekodieren, JSON parsen. Das alleine validiert NICHTS — du siehst nur, was im Token steht. Validierung verlangt drei Schritte: Signatur pruefen, Claims pruefen, Algorithmus pruefen.

Die Signatur deckt die ersten beiden Teile als base64url(header) + "." + base64url(payload) mit dem im alg-Header-Claim angegebenen Verfahren ab. HS256 nutzt HMAC-SHA-256 mit einem geteilten Geheimnis, RS256 RSA-PKCS1-v1.5 mit SHA-256 (privater Schluessel zum Signieren, oeffentlicher zum Pruefen), ES256 ECDSA P-256, PS256 RSASSA-PSS, EdDSA Ed25519. Beim Pruefen MUSST du den alg-Wert auf eine Whitelist eingrenzen, sonst kann ein Angreifer mit alg: none oder einem ausgetauschten alg die Signatur umgehen (CVE-2015-9235, der beruehmte HS256/RS256-Confusion-Bug).

Nach der Signaturpruefung folgt die Claim-Validierung. exp (Expiration Time, Sekunden seit Unix Epoch) muss in der Zukunft liegen, nbf (Not Before) in der Vergangenheit, iat (Issued At) sollte plausibel sein. RFC 7519 empfiehlt ein leeway-Fenster von einigen Sekunden gegen Clock-Skew zwischen Issuer und Verifier — die meisten Bibliotheken (jose, jjwt, PyJWT) erlauben das per Parameter. iss (Issuer) und aud (Audience) MUSST du selbst pruefen, sonst akzeptierst du fremde Tokens: ein Token, das fuer Dienst A ausgestellt wurde, darf bei Dienst B nicht gueltig sein, auch wenn beide den gleichen Issuer haben.

Header- und Payload-Felder im Detail

Diese Felder kommen in fast jedem produktiv genutzten JWT vor. Andere Claims sind erlaubt, koennen aber implementation-spezifisch sein.

  • Header alg: Signaturalgorithmus, z.B. HS256, RS256, ES256, EdDSA, none (nie akzeptieren). Definiert in RFC 7518 (JWA).
  • Header kid: Key ID. Erlaubt dem Verifier, aus mehreren Schluesseln den passenden auszuwaehlen — Pflicht beim Key-Rotation-Setup (z.B. JWKS-Endpunkte bei OAuth2/OIDC).
  • Payload exp / nbf / iat: NumericDate-Werte in Sekunden seit Unix Epoch. 1700000000 = 2023-11-14 22:13:20 UTC.
  • Payload iss / aud / sub: Issuer, Audience, Subject. aud kann ein String oder Array sein, was beim Parsing oft Bugs verursacht — immer auf beide Faelle pruefen.
  • Payload jti: eindeutige Token-ID. Pflicht fuer ein Token-Blacklist-/Revocation-System; idealerweise UUIDv4 oder kryptografisch sichere Zufallszeichenkette.

Beispiel-Tokens und ihre Bedeutung

Diese Header- und Payload-Beispiele zeigen, welche Felder du in echten APIs siehst und was sie aussagen.

  • {"alg":"HS256","typ":"JWT"} — Standard-Header fuer symmetrische Signatur, typisch bei selbst-betriebenen Auth-Servern oder Frameworks wie Devise (Rails) und Laravel Sanctum.
  • {"alg":"RS256","typ":"JWT","kid":"abc-2024-01"} — asymmetrisch mit Key-Rotation. Das kid verweist auf einen Public Key im JWKS unter /.well-known/jwks.json.
  • {"sub":"42","iat":1700000000,"exp":1700003600,"iss":"https://auth.example.com","aud":"api.example.com"} — Stunden-gueltiges Access-Token fuer User 42, ausgestellt von einem zentralen Auth-Server.
  • {"sub":"user-7","scope":"read:profile write:posts","exp":...} — OAuth2 Scope-Claim mit Space-getrennter Liste. Auth-Server wie Auth0, Keycloak und Okta nutzen das Format.
  • OIDC ID-Token: {"iss":"https://accounts.google.com","sub":"110...","aud":"client-id","email":"[email protected]","email_verified":true,"nonce":"..."} — die nonce muss mit der vom Client gesendeten uebereinstimmen.

Sicherheitsrisiken und bekannte Fehler

JWT ist sicher, wenn man es richtig benutzt — und unsicher, wenn nicht. Der erste klassische Fehler ist alg: none: einige Libraries akzeptieren ein Token ohne Signatur, wenn der Header das vorschreibt. Whitelist deine Algorithmen serverseitig hart. Zweiter Fehler: HS256/RS256-Confusion. Wenn der Verifier den oeffentlichen RSA-Schluessel als HMAC-Secret nutzt, kann ein Angreifer ein Token mit alg: HS256 signieren, das mit dem Public Key als Secret "verifiziert" wird. Dritter Fehler: keine Revocation. JWT ist bewusst stateless — wer einmal ausgestellt wurde, ist bis exp gueltig. Wer Logout oder Token-Sperrung braucht, muss eine Blacklist mit jti fuehren oder kurze exp + Refresh-Tokens verwenden. Vierter Fehler: zu viele Claims. JWTs landen in Cookies, Authorization-Headern und Logs — jeder Claim erhoeht die Groesse und damit die HTTP-Header-Limits (ueblicherweise 8 KB bei nginx). Persoenliche Daten gehoeren nicht in einen Bearer-Token, weil sie an alle Resource-Server fliessen, die ihn sehen. Fuenfter Fehler: keine TLS. Ein JWT ohne HTTPS ist effektiv ein Session-Token in Klartext — wer es abfaengt, ist der Nutzer.

Haeufige Fragen zu JWT

Wie verifiziere ich ein JWT serverseitig?
Mit einer Library wie jose (Node), PyJWT (Python), jjwt (Java) oder firebase/php-jwt (PHP). Wichtig: algorithms-Parameter explizit setzen, niemals der alg-Header des Tokens vertrauen. Den Public Key/Secret extern beziehen, idealerweise per JWKS.
Kann ich ein JWT ablaufen lassen, bevor exp erreicht ist?
Nicht direkt — JWT ist per Design stateless. Workarounds: eine serverseitige Blacklist mit den jti-Werten gesperrter Tokens, oder eine globale "min issued at"-Zeit pro User, die alle Tokens davor verwirft. Beides macht den stateless-Vorteil zunichte.
Wo speichere ich ein JWT im Browser?
Am sichersten ist ein HttpOnly-Cookie mit Secure und SameSite=Lax, weil JavaScript nicht zugreifen kann (XSS-sicher). LocalStorage ist verwundbar gegen XSS, gilt aber bei vielen SPA-Architekturen als Standard. Niemals in der URL — landet sonst in Server-Logs, Referer-Headern und Browser-History.
Was bedeutet der Fehler "jwt malformed"?
Das Token hat nicht das Format header.payload.signature mit genau zwei Punkten. Haeufige Ursachen: Whitespace, doppelter Bearer -Praefix im Authorization-Header, abgeschnittenes Token wegen Header-Groessen-Limits oder ein leerer String, wenn das Cookie noch nicht gesetzt war.
Was ist der Unterschied zwischen JWT und OAuth2?
OAuth2 (RFC 6749) ist ein Autorisierungs-Framework, das Token an Clients ausstellt. JWT (RFC 7519) ist ein Token-Format. Viele OAuth2-Provider nutzen JWT als ihr Access-Token-Format, aber OAuth2 schreibt das nicht vor — Token koennen auch opake Strings sein. Umgekehrt kann ein JWT auch komplett ohne OAuth2 eingesetzt werden, z.B. fuer interne Service-Calls.
Werden meine Token bei diesem Tool gespeichert?
Nein. Der Decoder laeuft komplett im Browser. Das Token verlaesst deinen Rechner nicht, es wird kein Logging gemacht. Du kannst die Implementierung in den DevTools nachvollziehen oder die Seite offline laden. Trotzdem: produktive Token niemals in fremde Online-Tools einfuegen, falls du die Quelle nicht selbst auditieren kannst.

Verwandte Tools