So funktioniert ein JWT
Ein JSON Web Token (RFC 7519) besteht aus drei durch Punkte verbundenen Textteilen. Der Header sagt, wie das Token signiert ist, die Payload enthält die Claims, etwa wer der Benutzer ist und wann das Token abläuft, und die Signatur beweist, dass beide von jemandem mit dem Schlüssel erstellt wurden. Header und Payload sind JSON in Base64url, einer Variante von Base64, die in URLs sicher ist.
header.payload.signature
header = base64url(UTF-8 JSON, e.g. {"alg":"HS256","typ":"JWT"})
payload = base64url(UTF-8 JSON with the claims)
signature = base64url(HMAC-SHA256(secret, header + "." + payload)) Base64url ist eine Kodierung, keine Verschlüsselung: Jeder, der ein Token hat, kann seine Payload lesen, genau wie diese Seite, ohne jeden Schlüssel. Legen Sie daher nie Passwörter oder andere Geheimnisse in ein JWT. Was der Schlüssel schützt, ist die Signatur: Ändern Sie ein Zeichen der Payload, und die Signatur stimmt nicht mehr.
Bei HS256, HS384 und HS512 teilen sich Aussteller und Server ein Secret und signieren mit HMAC; diese Seite kann sie prüfen, wenn Sie das Secret eingeben. RS256, ES256 und die anderen Public-Key-Algorithmen werden mit einem privaten Schlüssel signiert und mit dem öffentlichen Schlüssel des Ausstellers geprüft, den ein Server meist von einer JWKS-URL bezieht. Ein Token zu dekodieren heißt nicht, ihm zu vertrauen: Ein Server muss die Signatur, den Ablauf und die Audience prüfen.
Beispiel
Nehmen Sie das bekannte Beispiel von jwt.io: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c. Der erste Teil dekodiert zum Header {"alg":"HS256","typ":"JWT"}: eine HMAC-SHA256-Signatur. Der zweite dekodiert zur Payload {"sub":"1234567890","name":"John Doe","iat":1516239022}. Ihr iat von 1516239022 bedeutet, dass das Token am 18. Januar 2018 um 01:30:22 UTC ausgestellt wurde, und ohne exp läuft es nie ab. Der letzte Teil ist der 32 Byte lange HMAC-SHA256 der ersten beiden Teile und des Punkts dazwischen; mit dem Secret your-256-bit-secret stimmt er überein, die Signatur ist also gültig.
Die registrierten Claims
| Claim | Bedeutung |
|---|---|
iss · Aussteller | Wer das Token erstellt und signiert hat, meist die URL des Login-Dienstes. |
sub · Subjekt | Um wen es im Token geht, meist eine Benutzer-ID. |
aud · Adressat | Für wen das Token gedacht ist. Ein Server sollte ein Token ablehnen, dessen Audience nicht er selbst ist. |
exp · Läuft ab am | Nach diesem Zeitpunkt muss das Token abgelehnt werden. Sekunden seit dem 1. Januar 1970 UTC. |
nbf · Nicht vor | Vor diesem Zeitpunkt muss das Token abgelehnt werden. Sekunden seit dem 1. Januar 1970 UTC. |
iat · Ausgestellt am | Wann das Token erstellt wurde. Sekunden seit dem 1. Januar 1970 UTC. |
jti · Token-ID | Eine eindeutige ID für dieses Token, damit ein Server es sperren oder eine doppelte Verwendung bemerken kann. |
Fragen
Ist es sicher, mein JWT hier einzufügen?
Ja. Das Token wird von JavaScript in Ihrem Browser dekodiert, und die Signatur wird mit der eingebauten WebCrypto Ihres Browsers geprüft. Weder das Token noch das Secret wird an einen Server gesendet oder gespeichert. Behandeln Sie ein gültiges Token trotzdem wie ein Passwort: Wer es hat, kann es bis zum Ablauf nutzen.
Lässt sich ein JWT ohne das Secret dekodieren?
Ja. Header und Payload sind nur Base64url-kodiertes JSON, jeder kann sie ohne Schlüssel lesen. Das Secret oder der öffentliche Schlüssel wird nur gebraucht, um zu prüfen, ob die Signatur echt ist. Deshalb darf ein JWT keine Passwörter oder andere Geheimnisse enthalten.
Wie prüfe ich, ob ein JWT abgelaufen ist?
Sehen Sie sich den Claim exp an: Er ist die Ablaufzeit in Sekunden seit dem 1. Januar 1970 UTC. Liegt die aktuelle Zeit danach, ist das Token abgelaufen. Diese Seite liest exp und nbf für Sie und zeigt das Ergebnis als Datum und als „vor 3 Tagen abgelaufen“ oder „läuft in 2 Stunden ab“.
Was ist der Unterschied zwischen HS256 und RS256?
HS256 signiert mit HMAC und einem gemeinsamen Secret: Wer ein Token prüfen kann, kann auch eines erstellen. RS256 signiert mit einem privaten RSA-Schlüssel und wird mit dem öffentlichen Schlüssel geprüft, sodass Dienste Tokens verifizieren können, ohne sie ausstellen zu können. RS256 oder ES256 ist die übliche Wahl, wenn mehrere Dienste dieselben Tokens prüfen.
Warum ist die Signatur meines JWT ungültig?
Das Secret ist falsch, es ist Base64-kodiert und braucht die Option „Base64-kodiert“, oder das Token wurde nach dem Signieren verändert. Auch beim Kopieren eines Tokens können Zeichen hinzukommen oder fehlen. Nutzt das Token RS256, ES256 oder einen anderen Public-Key-Algorithmus, lässt es sich gar nicht mit einem Secret prüfen: Es braucht den öffentlichen Schlüssel des Ausstellers.