Die Kurzfassung lautet: JWK ist ein kryptografischer Schlüssel im JSON-Format; JWKS ist ein JSON Web Key Set, also eine Sammlung solcher Schlüssel. In der Praxis wird der Unterschied bei kid, Rotation, Discovery, Caching und sicherer Schlüsselauswahl wichtig.
Zum Inspizieren eines einzelnen Keys nutze ich den JWK Inspector; für Token + Key Set den JWKS Validator.
Eine JWK beschreibt genau einen Schlüssel
Ein RSA Public Key kann beispielsweise so aussehen:
{
"kty": "RSA",
"kid": "prod-2026-09",
"use": "sig",
"alg": "RS256",
"n": "...",
"e": "AQAB"
}
Wichtige Felder sind:
kty: Schlüsseltyp, z. B. RSA oder EC;kid: Key ID zur Auswahl;use: beabsichtigte Verwendung, häufigsig;key_ops: erlaubte Operationen, wenn vorhanden;alg: deklarierter Algorithmus, wenn vorhanden;- RSA:
n,e; - EC:
crv,x,y.
kid macht einen Key nicht vertrauenswürdig. Es ist primär ein Auswahl-Identifier.
Ein JWKS enthält mehrere JWKs
Ein Set sieht typischerweise so aus:
{
"keys": [
{ "kty": "RSA", "kid": "old", "alg": "RS256", "use": "sig", "n": "...", "e": "AQAB" },
{ "kty": "RSA", "kid": "new", "alg": "RS256", "use": "sig", "n": "...", "e": "AQAB" }
]
}
Mehrere Keys sind normal, besonders während Rotation. Der Verifier muss den passenden Kandidaten auswählen und anschließend prüfen, ob Key-Typ, Algorithmus und Operation zum Token passen.
So verbinde ich JWT kid mit dem JWKS
Header:
{ "alg": "RS256", "kid": "new" }
Selection-Logik:
JWT kid = new
↓
JWKS keys durchsuchen
↓
passenden kid finden
↓
kty/use/key_ops/alg prüfen
↓
Signatur verifizieren
Wenn kein Key passt, ist meine erste Frage nicht „Wie ignoriere ich kid?“, sondern „Ist das JWKS aktuell und gehört es zum erwarteten Issuer?“
jwks_uri gehört in eine Vertrauenskette
Bei OAuth/OIDC kann Metadata eine jwks_uri veröffentlichen. Ich baue die Kette so auf:
expected issuer
↓
vertrauenswürdige Discovery-/Metadata-URL
↓
jwks_uri aus dieser Metadata
↓
geladenes JWKS
↓
matching kid
↓
Signaturprüfung
Ich folge nicht automatisch einer beliebigen jku-URL aus einem untrusted JWT Header und erkläre den dort gefundenen Key anschließend für vertrauenswürdig.
Warum use, key_ops und alg relevant sind
Selbst mit passendem kid filtere ich Kandidaten. Ein Key mit use: "enc" ist beispielsweise nicht derselbe Zweck wie ein Signatur-Key. key_ops kann Operationen weiter begrenzen.
Ich erwarte außerdem eine sinnvolle Kombination:
JWT alg = RS256
JWK kty = RSA
und nicht etwa RS256 mit einem EC-Key.
Der JWKS Validator prüft diese Kompatibilität vor der Signaturprüfung.
Wie ich mit fehlendem oder doppeltem kid umgehe
Problemfälle:
- JWT hat
kid, JWKS enthält keinen Treffer; - mehrere Keys haben denselben
kid; - JWT hat kein
kid, Set enthält mehrere kompatible Keys; - Treffer hat falschen
kty/alg/use; - alter Key wurde während Rotation zu früh entfernt.
Ich vermeide „nimm einfach den ersten Key“. Ambiguität ist ein Signal, die Auswahl explizit zu klären.
Caching und Key Rotation
JWKS werden üblicherweise gecacht. Zwei Extreme sind problematisch:
- bei jedem Request neu laden: unnötige Last und Abhängigkeit vom Issuer;
- für immer cachen: neue Keys werden nie sichtbar.
Ein sinnvolles Muster ist Cache + kontrollierter Refresh bei unbekanntem kid, mit Rate Limiting und weiterhin an die vertrauenswürdige JWKS-Quelle gebunden. Details behandle ich im Key-Rotation-Guide.
JWK Thumbprint ist nicht dasselbe wie kid
RFC 7638 definiert einen kanonisch berechneten JWK Thumbprint. Ein kid ist dagegen ein vom Herausgeber gewählter Identifier. Ein Thumbprint kann helfen, Key-Material stabil zu vergleichen, aber er ersetzt nicht automatisch die Issuer-/Trust-Konfiguration.
Der JWK Inspector berechnet den Thumbprint lokal.
Meine Entscheidungsmatrix
| Frage | JWK | JWKS |
|---|---|---|
| Beschreibt genau einen Schlüssel? | ja | nein, Set |
Enthält keys-Array? | nein | ja |
| Für Rotation geeignet? | allein begrenzt | ja, mehrere Keys parallel |
kid-Auswahl nötig? | optional | häufig |
| Typischer Metadata-Verweis | direkter Key selten | jwks_uri |
Mein sicherer JWKS-Workflow
- Ich bestimme den erwarteten Issuer aus der Anwendungskonfiguration.
- Ich verwende dessen vertrauenswürdige Metadata/JWKS-Quelle.
- Ich dekodiere JWT Header
algundkidnur als Auswahlhinweise. - Ich suche nach dem passenden
kid. - Ich filtere
kty,use,key_ops,algund bei EC die Kurve. - Ich behandle fehlende oder mehrdeutige Treffer als Fehler statt den ersten Key zu nehmen.
- Ich verifiziere die Signatur über die originalen
header.payload-Bytes. - Danach validiere ich
iss,aud,expund weitere Claims. - Bei unbekanntem
kiduntersuche ich Cache/Rotation kontrolliert.
Der praktische Unterschied lautet damit nicht nur „ein Key gegen mehrere Keys“. JWKS ist Teil eines Key-Discovery- und Lifecycle-Prozesses; Vertrauen entsteht erst durch die Bindung an den erwarteten Issuer und erfolgreiche kryptografische Prüfung.