Skip to content
Back to Blog
developerjwt-decodersecurityauthentication

JWT dekodieren vs. verifizieren: Der entscheidende Unterschied

Jeder kann ein JWT base64-dekodieren und lesen, das ist nicht dasselbe wie Verifizieren. Hier erfahren Sie den Unterschied, die Angriffe, die diese Lücke ausnutzen, und wie Sie sicher dekodieren.

SZ
Founder, Molixa
10 min read
Teilen
JWT dekodieren vs. verifizieren: Der entscheidende Unterschied
Table of contents7 sections

Um einen JWT zu decodieren, base64url-decodieren Sie seine ersten beiden durch Punkte getrennten Teile, um den Header und die Nutzlast als JSON zu lesen. Decodieren ist nur Lesen: es überspringt die Signatur, sagt Ihnen also, was die Claims aussagen, nicht ob sie echt sind. Verifizieren ist der separate Schritt, der beweist, dass der Token nicht manipuliert wurde.

Diese Unterscheidung ist der Kern der Sache. Ein JWT ist signiert, nicht verschlüsselt, was bedeutet, dass jeder, der den Token besitzt, jeden darin enthaltenen Claim ohne Schlüssel lesen kann. Die Annahme "Ich habe ihn decodiert und die Claims sehen richtig aus" als Authentizitätsnachweis zu behandeln, ist der Weg, wie echte Sicherheitslücken in die Produktion gelangen. Lassen Sie uns einen Token auseinandernehmen, genau sehen, wo die Decodierung endet und die Verifizierung beginnt, und dann die Angriffe behandeln, die in dieser Lücke lauern.

Was ein JWT tatsächlich enthält#

Ein JSON Web Token besteht aus drei base64url-codierten Abschnitten, die durch Punkte getrennt sind:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IkFkYSIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTczNTY4OTYwMH0.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Die drei Teile sind header.payload.signature. Dekodiert man die ersten beiden, erhält man lesbares JSON:

// Header
{ "alg": "HS256", "typ": "JWT" }

// Payload (die Claims)
{ "sub": "1234", "name": "Ada", "role": "admin", "exp": 1735689600 }

alg gibt an, welcher Algorithmus den Token signiert hat (hier HMAC-SHA256). Der Payload enthält Claims: sub (Subject/Benutzer-ID), role und exp (Ablaufdatum als Unix-Zeitstempel). Der dritte Teil, die Signatur, ist ein keyed Hash der ersten beiden. Entscheidend ist: Der Payload ist nur base64url-codiert, also eine Kodierung, keine Verschlüsselung. Setzen Sie niemals ein Geheimnis in einen JWT-Payload. Jeder kann ihn lesen.

Base64url ist eine URL-sichere Variante von base64: Sie ersetzt + und / durch - und _ und entfernt Padding. Wenn Sie schon einmal versucht haben, einen JWT mit einem Standard-base64-Tool zu dekodieren und einen Fehler erhalten haben, liegt das meist am Zeichensatz.

Decode vs Verify: Der entscheidende Unterschied#

Diese beiden Vorgänge sehen ähnlich aus und werden in Tutorials ständig verwechselt. Sie sind nicht identisch, und ihre Verwechslung ist ein Sicherheitsfehler.

DecodeVerify
Was es tutLiest Header und PayloadBestätigt, dass die Signatur gültig ist
Benötigt einen Schlüssel?NeinJa (geheimer oder öffentlicher Schlüssel)
Kann ein Fremder es tun?Ja, mit jedem Base64-ToolNein, nur der Gegenüber des Unterzeichners
Beweist Authentizität?NeinJa
Wann verwendenDebugging, Überprüfung von ClaimsJedes Mal, wenn Sie dem Token vertrauen

Hier ist der Unterschied im Code. Decodieren ist trivial und erfordert kein Vertrauen:

// NUR DECODIEREN: liest Claims, beweist nichts
function decodeJwt(token) {
  const [header, payload] = token.split(".");
  const json = (part) =>
    JSON.parse(atob(part.replace(/-/g, "+").replace(/_/g, "/")));
  return { header: json(header), payload: json(payload) };
}

const { payload } = decodeJwt(token);
console.log(payload.role); // "admin" ... aber ist dieses Token überhaupt echt?

Dieser Code gibt fröhlich role: "admin" für jedes Token zurück, das Sie ihm geben, einschließlich eines, das ein Angreifer vor fünf Sekunden gefälscht hat. Verifizieren macht die Claims vertrauenswürdig:

// VERIFIZIEREN: prüft Signatur und Ablauf, bevor etwas geglaubt wird
import jwt from "jsonwebtoken";

try {
  const claims = jwt.verify(token, process.env.JWT_SECRET, {
    algorithms: ["HS256"], // Algorithmus explizit festlegen
  });
  // Erst jetzt ist claims.role sicher zu verwenden
  grantAccess(claims.role);
} catch (err) {
  // Signatur ungültig, Token abgelaufen oder Algorithmus nicht erlaubt
  denyAccess();
}

Die Regel ist einfach: Decodieren zum Anschauen, Verifizieren zum Vertrauen. Jeder Codepfad, der eine Autorisierungsentscheidung trifft, muss verifizieren. Decodieren ohne Verifizieren auf dem Server ist gleichbedeutend damit, Benutzern zu erlauben, ihre eigenen Berechtigungen zu bearbeiten.

Die Angriffe, die in der Lücke lauern#

Wenn Entwickler die Verifizierung überspringen oder falsch handhaben, eröffnen sich drei klassische Angriffe. Alle nutzen aus, dass das Token bis zur korrekten Signaturprüfung vom Angreifer kontrolliert wird.

Der "none"-Algorithmus-Angriff#

Die JWT-Spezifikation enthält einen alg-Wert none, der für "unsigniert" steht. Wenn ein Server den Algorithmus aus dem Header des Tokens selbst ausliest und ihm vertraut, kann ein Angreifer die Signatur entfernen, "alg": "none" setzen und jede beliebige Nutzlast fälschen:

// Gefälschter Header des Angreifers
{ "alg": "none", "typ": "JWT" }

// Gefälschte Nutzlast des Angreifers: sofort Admin
{ "sub": "9999", "role": "admin" }

Mit entfernter Signatur und auf none gesetztem alg akzeptiert ein naiver Prüfer, der den Header "ehrt", das Token. Die Lösung ist, dem Token niemals zu erlauben, seinen eigenen Algorithmus zu bestimmen. Legen Sie den erwarteten Algorithmus serverseitig fest, genau wie bei der Option algorithms: ["HS256"] oben, sodass none und jeder andere unerwartete Wert sofort abgewiesen werden.

Der Algorithmus-Verwechslungsangriff (RS256 zu HS256)#

Dieser ist subtiler und hat große Bibliotheken getroffen. Angenommen, Ihr System signiert Tokens mit RS256 (asymmetrisch: ein privater Schlüssel signiert, ein öffentlicher Schlüssel verifiziert). Der öffentliche Schlüssel ist per Definition öffentlich.

Ein Angreifer nimmt diesen öffentlichen Schlüssel, ändert den Header auf "alg": "HS256" (symmetrisches HMAC) und signiert ein gefälschtes Token mit dem öffentlichen Schlüssel als HMAC-Geheimnis. Ein verwundbarer Prüfer, der den Algorithmus aus dem Header auswählt, führt nun die HMAC-Verifizierung mit dem bereits vorhandenen öffentlichen Schlüssel durch, und die gefälschte Signatur ist gültig. Der Angreifer hat einfach Ihren veröffentlichten Verifizierungsschlüssel verwendet, um Tokens zu signieren.

Die Verteidigung ist dasselbe Prinzip: Legen Sie den Algorithmus fest. Wenn Ihr Server RS256 erwartet, konfigurieren Sie ihn so, dass er nur RS256 akzeptiert und mit dem öffentlichen Schlüssel als RSA-Schlüssel verifiziert, niemals als HMAC-Geheimnis. Dem Header die Wahl zu lassen, ist jedes Mal die Ursache.

Ignorieren von Ablauf und anderen Ansprüchen#

Selbst eine perfekt verifizierte Signatur bedeutet nicht, dass das Token aktuell gültig ist. Die Verifizierung bestätigt, dass das Token von Ihnen ausgestellt und nicht verändert wurde; sie prüft jedoch nicht von selbst, ob das Token noch aktuell oder für diese Zielgruppe bestimmt ist. Validieren Sie immer:

  • exp (Ablauf) und nbf (Nicht-vor), damit abgelaufene oder zukünftige Tokens abgewiesen werden.
  • aud (Zielgruppe), damit ein für einen Dienst ausgestelltes Token nicht gegen einen anderen wiederverwendet werden kann.
  • iss (Aussteller), damit Sie nur Tokens von dem vertrauenswürdigen Identitätsanbieter akzeptieren.

Die meisten Bibliotheken prüfen exp automatisch, wenn Sie verify aufrufen, aber aud und iss erfordern in der Regel, dass Sie die erwarteten Werte explizit übergeben.

Auch der Speicherort und die Übertragung des Tokens sind entscheidend#

Die Verifizierung schützt den Inhalt des Tokens, aber die Handhabung des Tokens stellt eine eigene Angriffsfläche dar. Einige unverhandelbare Punkte:

  • HTTP-Only-Cookies bevorzugen gegenüber localStorage für Sitzungstoken, damit clientseitige Skripte (und etwaige XSS-Payloads) sie nicht lesen können.
  • Immer HTTPS verwenden, damit das Token nicht während der Übertragung abgefangen wird.
  • Payloads minimal und nicht sensibel halten. Da jeder die Nutzlast dekodieren kann, niemals Passwörter, vollständige personenbezogene Daten oder Geheimnisse darin speichern.
  • Kurze Lebensdauer plus Refresh-Token verwenden, sodass ein durchgesickertes Zugriffstoken schnell abläuft.

Ein durchgesickertes Token ist gültig, bis es abläuft. Deshalb sind Ablauffristen und Speicherhygiene genauso wichtig wie die Signaturberechnung.

Wie man ein JWT sicher zum Debuggen dekodiert#

Beim Erstellen von Authentifizierungssystemen müssen Sie ständig Tokens überprüfen: um zu sehen, welche Claims ein Identitätsanbieter ausgestellt hat, um einen 401-Fehler zu debuggen oder um das Ablaufdatum zu bestätigen. Die Krux ist, dass ein JWT eine aktive Berechtigung ist. Wenn Sie ein echtes Sitzungstoken in eine beliebige Website einfügen, hat der Server dieser Website jetzt ein gültiges Token für Ihr Konto.

Schritt 1: Verwenden Sie einen Dekodierer, der im Browser läuft#

Greifen Sie zu einem kostenlosen JWT-Dekodierer, der die gesamte Analyse clientseitig durchführt. Wenn die Dekodierung vollständig im Browser-Tab erfolgt, wird das Token nirgendwohin übertragen, sodass selbst ein Produktionstoken auf Ihrem Rechner bleibt. Dies ist die wichtigste Gewohnheit beim Umgang mit echten Tokens: Bestätigen Sie vor dem Einfügen, dass das Tool clientseitig arbeitet.

Schritt 2: Header, Payload und Ablaufdatum lesen#

Der Dekodierer teilt das Token und zeigt Header und Payload als formatiertes JSON sowie ein lesbares Ablaufdatum an, sodass Sie keinen Unix-Timestamp manuell umrechnen müssen. Prüfen Sie den alg, überfliegen Sie die Claims und bestätigen Sie, dass exp in der Zukunft liegt. Denken Sie daran: Sie lesen in dieser Phase, nicht validieren.

Schritt 3: Signatur nur mit einem Nicht-Produktions-Geheimnis verifizieren#

Wenn der JWT-Dekodierer und -Verifizierer das Testen einer Signatur erlaubt, fügen Sie niemals ein Produktions-Signing-Geheimnis in ein Webformular ein, sondern nur ein Test- oder Entwicklungsgeheimnis. Die Signaturberechnung können Sie auch lokal durchführen: Eine HS256-Signatur ist lediglich ein HMAC, den Sie mit einem Hash-Generator berechnen können, und die Base64url-Teile dekodieren Sie mit einem Base64-Kodierer und -Dekodierer. Für einen umfassenderen Blick auf den sicheren Umgang mit Tokens lesen Sie unseren Leitfaden zu JWT-Dekodierern und Token-Sicherheit.

Das Fazit#

Das Dekodieren eines JWT liest die Claims; die Verifizierung beweist deren Authentizität. Es handelt sich um unterschiedliche Vorgänge mit unterschiedlichen Anforderungen, und ihre Vermischung ist die Ursache für den none-Algorithmus und Algorithmen-Verwechslungsangriffe. Auf dem Server muss jedes Token verifiziert, der Algorithmus explizit festgelegt und exp, aud sowie iss geprüft werden. Zum Debuggen dekodieren Sie lokal, damit ein Live-Zugangsdaten nie Ihren Browser verlassen.

Häufig gestellte Fragen#

Wie dekodiere ich ein JWT? Teilen Sie das Token an den beiden Punkten in drei Teile und decodieren Sie dann den ersten Teil (Header) und den zweiten Teil (Payload) mit Base64url in JSON. Der dritte Teil ist die Signatur und ist nicht zum Lesen bestimmt. Das Dekodieren erfordert keinen Schlüssel und zeigt Ihnen nur die Claims, es bestätigt nicht die Authentizität des Tokens.

Was ist der Unterschied zwischen Dekodieren und Verifizieren eines JWT? Dekodieren liest Header und Payload und benötigt keinen Schlüssel, sodass jeder dies tun kann. Verifizieren berechnet die Signatur mit dem geheimen oder öffentlichen Schlüssel neu, um zu bestätigen, dass das Token von Ihnen ausgestellt und nicht verändert wurde. Dekodieren sagt Ihnen, was die Claims aussagen; nur Verifizieren sagt Ihnen, ob Sie ihnen vertrauen können.

Ist es sicher, ein JWT online zu dekodieren? Nur mit einem Tool, das vollständig in Ihrem Browser dekodiert. Ein JWT ist eine aktive Berechtigung. Wenn Sie ein echtes Sitzungstoken in eine Website einfügen, die es an einen Server sendet, übergeben Sie diesem Server ein funktionierendes Token für Ihr Konto. Verwenden Sie einen clientseitigen Decoder, damit das Token Ihren Tab nie verlässt.

Was ist der JWT-Angriff mit dem Algorithmus "none"? Er nutzt Server aus, die den Signaturalgorithmus aus dem eigenen Header des Tokens lesen. Ein Angreifer setzt "alg": "none", entfernt die Signatur und fälscht einen beliebigen Payload. Ein Verifizierer, der den Header beachtet, akzeptiert das unsignierte Token. Die Lösung ist, den erwarteten Algorithmus auf dem Server festzulegen und none grundsätzlich abzulehnen.

Kann jemand die Daten in meinem JWT lesen? Ja. Ein JWT ist signiert, nicht verschlüsselt. Der Payload ist nur Base64url-kodiert, und jeder, der das Token besitzt, kann jeden Claim dekodieren und lesen. Speichern Sie niemals Passwörter, Geheimnisse oder sensible persönliche Daten in einem JWT-Payload. Die Signatur schützt vor Manipulation, nicht vor dem Lesen.

Wie überprüfe ich, ob ein JWT abgelaufen ist? Dekodieren Sie den Payload und lesen Sie den exp-Claim, einen Unix-Zeitstempel in Sekunden. Wenn er in der Vergangenheit liegt, ist das Token abgelaufen. Bei der echten Verifizierung lehnen die meisten Bibliotheken abgelaufene Token automatisch ab, wenn Sie verify aufrufen. Ein Decoder, der ein lesbares Ablaufdatum anzeigt, ermöglicht Ihnen, dies beim Debuggen schnell zu bestätigen.

developerjwt-decodersecurityauthentication

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools
JWT dekodieren vs. verifizieren: Sicherheitsleitfaden | Molixa | Molixa