Signierte JSON Web Tokens mit HMAC-SHA256/384/512 erzeugen
{{ error }}
Ein JSON Web Token (JWT, RFC 7519) ist ein kompakter, signierter Container für JSON-Daten. Er besteht aus drei Base64URL-kodierten Teilen, durch Punkte getrennt: Header (Algorithmus), Payload (Claims) und Signature. JWTs werden für stateless Authentifizierung in APIs (Bearer-Token), OAuth/OpenID Connect und Single-Sign-On eingesetzt.
HS256/384/512 sind symmetrische HMAC-Algorithmen — Sender und Empfänger teilen denselben Secret. Sie sind einfach und schnell, eignen sich für interne APIs. Für öffentliche APIs nutzt man asymmetrisches RS256 oder ES256 (Public-/Private-Key) — diese werden vom Web Crypto API ebenfalls unterstützt, sind aber komplexer in der Schlüsselverwaltung. `none` (unsigned) sollte niemals in Produktion verwendet werden.
Ein JWT wird in drei Schritten gebaut. Zuerst werden Header und Payload je als JSON serialisiert. Dann durchlaeuft jeder Teil Base64URL-Encoding (RFC 4648 §5) — die URL-sichere Variante mit -/_ statt +//, ohne Padding-Gleichheitszeichen. Aus diesen beiden kodierten Strings wird der signing input als base64url(header) + "." + base64url(payload). Erst dieser komplette String wird signiert, nicht der Roh-JSON. Das ist wichtig: zwei semantisch identische, aber verschieden serialisierte Header (anderes Key-Order, Whitespace) ergeben verschiedene Signaturen — wer Tokens vergleicht, muss die kanonische Form nehmen, nicht die geparsten Objekte.
Die HMAC-Familie (HS256/384/512) verwendet einen geteilten Schluessel und ist symmetrisch — wer signieren kann, kann auch verifizieren. Praktisch fuer monolithische Apps mit einem einzigen Backend, problematisch sobald mehrere Services verifizieren sollen, weil das Secret in jedem davon liegen muss. RS256 (RSA-PKCS1-v1.5 + SHA-256, RFC 3447) und ES256 (ECDSA mit P-256) sind asymmetrisch: der Issuer haelt den Private Key, alle Verifier brauchen nur den Public Key — der per JWKS-Endpunkt unter /.well-known/jwks.json verteilt wird. Fuer neue Systeme empfiehlt RFC 8037 ausdruecklich EdDSA (Ed25519): keine Padding-Tricks, deutlich kuerzere Signaturen (~88 Byte Base64 statt 256 Byte fuer 2048-Bit-RSA) und konstantzeitige Verifizierung.
alg: none ist im Standard erlaubt und sorgt seit Jahren fuer Sicherheitsluecken. Die offizielle Empfehlung der RFC 8725 ("JWT Best Current Practices") lautet: never accept alg: none. Beim Verifier strikte Algorithm-Whitelist, idealerweise ein konkreter Algorithmus pro Endpoint. Die zweite Praxisempfehlung: typ auf JWT setzen, cty nur bei nested JWS/JWE. Der dritte Punkt: kid nutzen, sobald mehr als ein Key im Umlauf ist, damit Rotation moeglich wird. Beim Generator hier ist der Output das, was du in den Authorization-Header packen kannst: Authorization: Bearer <token>.
So baust du ein produktionsreifes Token, das gaengige Verifier akzeptieren.
{"alg":"HS256","typ":"JWT"} fuer einfache Setups oder {"alg":"RS256","typ":"JWT","kid":"key-2024-01"} bei Key-Rotation.iss (wer hat ausgestellt), sub (User-ID), aud (welcher Service darf das Token nutzen), iat, exp (Unix-Sekunden).roles, tenant_id, scope. Kein Passwort, keine PII — JWT ist nicht verschluesselt.openssl rand -base64 32. Niemals "secret" oder "changeme" in Produktion.Authorization: Bearer eyJhbGci.... Die Empfaengerseite verifiziert mit demselben Secret oder dem passenden Public Key.Diese Beispiele zeigen Payloads, wie sie in echten Production-Systemen erzeugt werden.
{"sub":"u_42","iat":1700000000,"exp":1700003600,"aud":"api.example.com","scope":"read:profile write:posts"} — eine Stunde gueltig.{"sub":"u_42","iat":...,"exp":...+2592000,"typ":"refresh","jti":"uuid-..."} — 30 Tage gueltig, mit jti fuer Revocation.{"sub":"u_42","purpose":"reset","iat":...,"exp":...+900,"jti":"..."} — 15 Minuten gueltig, einmalig nutzbar via jti-Blacklist.{"iss":"billing-svc","sub":"billing-svc","aud":"users-svc","iat":...,"exp":...+60} — sehr kurz lebig, identifiziert den aufrufenden Service.{"iss":"https://auth.example.com","sub":"user-42","aud":"client-id","email":"[email protected]","nonce":"...","iat":...,"exp":...} — Identitaetsnachweis fuer Login.Erster Punkt: das HS256-Secret muss kryptografisch zufaellig sein. Ein Woerterbuch-Wort wird in Sekunden geknackt — generiere mit openssl rand -base64 32 oder crypto.randomBytes(32). Zweiter Punkt: kurze exp-Zeiten. Access-Tokens sollten maximal 15 Minuten gueltig sein, ID-Tokens maximal eine Stunde, Refresh-Tokens duerfen laenger leben, brauchen dann aber Revocation. Dritter Punkt: Token-Groesse. Jedes Byte landet in jedem HTTP-Header. Bei mehr als 1 KB triggern manche Proxies und Loadbalancer einen 431 Request Header Fields Too Large. Vierter Punkt: alg: none nutzt dieser Generator nur fuer Demos — niemals in Produktion akzeptieren. Fuenfter Punkt: die kryptografischen Operationen laufen hier im Browser via Web Crypto API; das Secret verlaesst dein Geraet nicht, aber es wird im JavaScript-Speicher gehalten. Vermeide dieses Tool fuer Produktions-Secrets auf ungeschuetzten Maschinen.
openssl rand -base64 32 oder node -e "console.log(require('crypto').randomBytes(32).toString('base64'))". Mindestlaenge: 256 Bit (32 Byte) fuer HS256, 384 Bit fuer HS384, 512 Bit fuer HS512. Speichere es in einem Secret-Manager wie Vault, AWS Secrets Manager oder Doppler — niemals im Git-Repo.iss, sub, aud, iat, exp. Fuer Revocation zusaetzlich jti. OIDC-Spec verlangt zusaetzlich nonce bei Authorization-Code-Flow mit Implicit-Anteil.exp sein?header.encryptedKey.iv.ciphertext.tag. In der Praxis brauchen die wenigsten APIs JWE — ueblicher ist TLS (das den ganzen Transport verschluesselt) plus eine signierte aber unverschluesselte JWS.crypto.subtle.sign). Es wird kein Request an einen Server gesendet, das Secret existiert nur in deinem RAM. Du kannst die Seite offline laden und es funktioniert weiter. Trotzdem gilt: Produktiv-Secrets nur auf einem Geraet eingeben, dem du komplett vertraust.