Utilo

Wie JWT funktioniert und wie man ein Token sicher entschlüsselt

Verständnis für die Struktur von JSON Web Token, wie Signaturen erstellt und verifiziert werden, häufige Ansprüche, Sicherheitslücken und die Entschlüsselung eines JWT.

· 5 Min. Lesezeit

JSON Web Token (JWTs) sind überall: OAuth- und OpenID Connect-Anmeldungen, API-Gateways, Single Sign-On zwischen Microservices und mobilen App-Sitzungen. Sie werden auch weit verbreitet missverstanden. Entwickler entschlüsseln ein Token, sehen lesbare JSON und fragen sich, ob das ein Sicherheitsproblem ist; andere speichern sensible Daten in Token, unter der Annahme, dass sie verschlüsselt sind. In diesem Artikel wird genau erklärt, was ein JWT ist, wie es validiert wird und wie man es ohne Risiko untersucht.

Die drei Teile eines JWT

Ein JWT sieht aus wie drei zufällige Strings, die durch Punkte verbunden sind:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTkwMDAwMDAwMH0.Kx8...

Jeder Teil ist Base64URL-kodiert:

  1. Header JSON, der den Token-Typ und den Signal-Algorithmus beschreibt, beispielsweise {"alg":"HS256","typ":"JWT"}.
  2. ** Payload** JSON mit Ansprüchen: Aussagen über den Benutzer und das Token, z. B. {"sub":"42","exp":1900000000}.
  3. Signatur Bytes, die aus dem Header und der Nutzlast mit einem geheimen oder privaten Schlüssel berechnet werden.

Base64URL ist eine Variante von [Base64] ((/blog/base64-explained), die - und _ anstelle von + und / verwendet und Polsterung fallen lässt, so dass Token in URLs und Header platziert werden können, ohne zu entkommen.

Wichtig ist, dass Kopf und Nutzlast nur verschlüsselt sind, nicht verschlüsselt. Jeder, der das Token hat, kann es lesen. Ein Token in einen [JWT-Decoder] ((/tools/jwt-decoder) kleben und die Nutzlast erscheint sofort das ist durch Design.

Wie die Signatur funktioniert

Die Unterschrift macht eine JWT vertrauenswürdig. Der Emittent nimmt den verschlüsselten Header und die Nutzlast, verbindet sie mit einem Punkt und unterschreibt die Zeichenfolge.

Bei HS256 (HMAC mit SHA-256) teilen sich Aussteller und Prüfer einen Geheimschlüssel:

signature = HMAC-SHA256(secret, base64url(header) + "." + base64url(payload))

Mit RS256 oder ES256 unterschreibt der Emittent mit einem privaten Schlüssel und jeder kann mit dem entsprechenden öffentlichen Schlüssel überprüfen, der oft an einem JWKS-Endpunkt wie https://login.example.com/.well-known/jwks.json veröffentlicht wird. Asymmetrische Algorithmen werden bevorzugt, wenn viele Dienste Token überprüfen müssen, aber nur einer sollte sie ausstellen.

Wenn ein Server einen Token empfängt, berechnet er die Signatur neu oder überprüft sie. Wenn nur ein Zeichen der Nutzlast geändert wird, sagen wir, ein Angreifer hat "role":"user" auf "role":"admin" bearbeitet, stimmt die Signatur nicht mehr überein und das Token wird abgelehnt.

Registrierte Ansprüche, die Sie kennen sollten

Die JWT-Spezifikation (RFC 7519) definiert Standardansprüche:

  • iss (Emittent): Wer hat das Token erstellt, z. B. https://login.example.com.
  • sub (Subjekt): Wer der Token ist, in der Regel eine Benutzer-ID.
  • aud (Publikum): Für wen das Token bestimmt ist, z. B. api.example.com.
  • exp (Verfalldatum): die Zeit, nach der das Token abgelehnt werden muss, in [Unix-Sekunden] ((/blog/unix-timestamp-explained).
  • nbf (nicht früher): die Zeit, vor der das Token nicht gültig ist.
  • iat (ausgegeben am): wenn das Token erstellt wurde.
  • jti (JWT-ID): ein eindeutiger Identifikator, der für Widerrufslisten nützlich ist.

Die Anträge fügen ihre eigenen Ansprüche hinzu: scope, roles, tenant_id, email. Halten Sie sie wenige; jede Forderung reist mit jeder Bitte.

Richtige Validierung eines Tokens

Ein Server muss in dieser Reihenfolge Folgendes überprüfen:

  1. Der Algorithmus ist derjenige, den Sie erwarten. Konfigurieren Sie eine Erlaubnisliste wie ["RS256"]. Lassen Sie niemals den Token-Header frei entscheiden; historische Schwachstellen erlauben Angreifern, auf none zu wechseln oder Server dazu zu bringen, einen öffentlichen Schlüssel als HMAC-Geheimnis zu verwenden.
  2. Die Signatur ist gültig mit dem richtigen Schlüssel, der von kid aus Ihrem vertrauenswürdigen Schlüsselsatz ausgewählt wurde.
  3. exp ist in der Zukunft und nbf in der Vergangenheit, was eine kleine Uhrverschiebung von 3060 Sekunden ermöglicht.
  4. iss passt genau zu Ihrem Identitätsanbieter.
  5. aud enthält die Kennung Ihres Dienstes, so dass ein Token, das für eine andere API ausgegeben wurde, nicht gegen Ihren wiedergegeben werden kann.

Verwenden Sie eine gepflegte Bibliothek jose für JavaScript, PyJWT für Python, golang-jwt für Go , anstatt die Überprüfung selbst zu schreiben.

Decodierung gegen Verifizierung

Decodierung bedeutet Base64URL-Decodierung der ersten beiden Teile und Parsing der JSON. Es erfordert keinen Schlüssel und beweist nichts über die Echtheit. Es ist nützlich für:

  • Fehlerbehebung, warum eine API 401 zurückgibt: Ist aud korrekt? Ist der Token abgelaufen?
  • Überprüfung, welche Bereiche oder Rollen ein Login-Flow tatsächlich gewährt.
  • Bestätigt, dass eine Token-Erneuerung einen neuen exp erzeugt hat.

Überprüfung bedeutet die Überprüfung der Unterschrift und der Ansprüche, wie oben beschrieben. Nur Server sollten Genehmigungsentscheidungen treffen und erst nach Überprüfung.

Front-End-Code kann ein Token entschlüsseln, um den Namen des Benutzers anzuzeigen oder eine Aktualisierung vor exp zu planen, aber es darf sich niemals auf entschlüsselte Sicherheitsansprüche verlassen, da ein Benutzer alles ändern kann, was in seinem Browser ausgeführt wird.

Wo Token im Browser gespeichert werden

Es gibt keine perfekte Antwort, nur Kompromisse:

  • HttpOnly, Secure, SameSite-Cookies können nicht von JavaScript gelesen werden, das durch Cross-Site-Skripting vor Token-Diebstahl schützt. Sie benötigen CSRF-Schutz, obwohl SameSite=Lax oder Strict die meisten Fälle abdeckt.
  • Speicher (eine JavaScript-Variable) ist vor Persistenz geschützt, aber beim Neuladen verloren; kombinieren Sie es mit einem Refresh-Token in einem HttpOnly-Cookie.
  • localStorage ist praktisch, aber von jedem Skript auf der Seite lesbar, so dass eine einzige XSS-Schwachstelle jedes Token durchsickert.

Für die meisten Web-Apps sind kurzlebige Zugriffs-Token im Speicher plus ein Refresh-Token in einem HttpOnly-Cookie eine gute Balance.

Verjährung und Widerruf

JWT sind staatenlos: Ein Server kann sie ohne Datenbanksuche validieren. Die Kehrseite ist, dass ein gültiges Token nicht leicht widerrufen werden kann, bevor es abläuft. Schadensminderungsmaßnahmen:

  • Aufbewahren von Zugangstoken 5 bis 15 Minuten ist üblich.
  • Verwenden Sie Refresh-Token, die sicher gespeichert und mit einer Datenbank überprüft werden, um neue Zugriffs-Token auszustellen.
  • Bei Aktionen mit hohem Risiko überprüfen Sie eine Widerrufsliste von jti-Werten oder einen Zeitstempel für "Token nach" pro Benutzer.

Häufige Fehler

  • ** Geheimnisse in die Nutzlast legen. ** Passwörter, API-Schlüssel und persönliche Daten sind für jeden mit dem Token lesbar. Wenn Sie Vertraulichkeit benötigen, verwenden Sie JWE (verschlüsselte Token) oder behalten Sie die Daten auf der Serverseite.
  • ** Sehr langlebige Token.** Ein gestohlenes Token, das ein Jahr gültig ist, ist ein einjähriges Verstoß.
  • ** Überspringen von Publikumsprüfungen.** Ohne aud-Validierung kann ein Token für einen Dienst mit niedrigem Privileg gegen einen Dienst mit hohem Privileg verwendet werden.
  • Schwache HMAC-Geheimnisse. HS256-Geheimnisse müssen lang und zufällig sein mindestens 256 Bits. Kurze Geheimnisse können offline mit einem einzigen Token gezwungen werden.
  • Logging-Token. Zugriffsprotokolle und Fehler-Tracker erfassen häufig Authorization-Header. Schreiben Sie sie aus.

Ein Token sicher zu überprüfen

Verwenden Sie beim Debuggen einen Decoder, der lokal in Ihrem Browser ausgeführt wird, damit das Token nie an Dritte gesendet wird. Bevorzugen Sie abgelaufene oder Testumgebungs-Token, wenn Sie Screenshots teilen oder in Tickets einfügen. Überprüfen Sie:

  • alg und kid im Header stimmen mit der Konfiguration Ihres Providers überein.
  • iss und aud entsprechen dem, was Ihre API erwartet.
  • exp, iat und nbf sind relativ zur aktuellen Zeit sinnvoll.
  • Umfang und Rollen enthalten, was die Operation erfordert.

Zusammenfassung

Ein JWT ist ein signiertes, nicht verschlüsseltes Bündel von JSON-Ansprüchen. Seine Sicherheit beruht ausschließlich auf der Signaturprüfung und der Validierung von Ansprüchen auf dem Server. Die Entschlüsselung ist harmlos und nützlich für das Debugging; das Vertrauen in entschlüsselte Daten ohne Überprüfung ist das eigentliche Risiko. Halten Sie Token kurzlebig, halten Sie Nutzlasten klein und frei von Geheimnissen, validieren Sie Algorithmen, Signaturen, Ablaufzeiten, Emittenten und Publikum jedes Mal und überprüfen Sie Token mit Tools, die sie auf Ihrem Computer aufbewahren.

Diese Seite wurde automatisch aus dem Englischen übersetzt. Wenn dir ein Fehler auffällt, sag uns bitte Bescheid.

Verwandte Ratgeber