De handtekening van een JSON Web Token (JWT) verifiëren
- Dashboard
- Documentatie
- API
Waarom de handtekening van een JWT verifiëren?
Een JSON Web Token (JWT) bestaat uit drie delen gescheiden door punten:
header.payload.signature. Een JWT decoderen bestaat eenvoudig uit het lezen van de eerste twee
delen (die Base64URL zijn). Iedereen kan het doen, en iedereen kan een JWT
met de payload van zijn keuze fabriceren. Wat een JWT betrouwbaar maakt, is alleen de
handtekening: zonder verificatie is een JWT accepteren hetzelfde als bij u thuis elke persoon binnenlaten die
beweert iemand te zijn, zonder identiteitsbewijs te vragen.
Deze tool verifieert de handtekening van een JWT vanuit een sleutel. Hij beperkt zich niet tot het decoderen: hij berekent de handtekening opnieuw vanuit de header, de payload en uw sleutel, en vergelijkt deze vervolgens met de handtekening van het token. Als beide overeenkomen, is het token authentiek. Anders is het gesmeed, gewijzigd of ondertekend met een andere sleutel.
De verificatie is de hoeksteen van elke architectuur die JWT's gebruikt voor
authenticatie of autorisatie: zonder geldige handtekening kan de payload liegen.
Een aanvaller die "role":"user" wijzigt naar "role":"admin" zou geen
moeite hebben om het te doen als de server alleen het formaat van het token verifieert en niet de handtekening.
Gangbare algoritmen
De JWT-specificatie (RFC 7518, JSON Web Algorithms) definieert verschillende families van algoritmen. Dit zijn de meest gebruikte in productie:
- HMAC (HS256, HS384, HS512): symmetrische handtekening gebaseerd op HMAC-SHA. De zelfde geheime sleutel dient om te ondertekenen en te verifiëren. Eenvoudig te implementeren, performant, maar elke partij die het token kan verifiëren is ook in staat om er een uit te geven. Geschikt voor scenario's waar de uitgever en de verificateur hetzelfde team of dezelfde service zijn.
- RSA (RS256, RS384, RS512): asymmetrische handtekening. De privésleutel ondertekent, de publieke sleutel verifieert. Ideaal wanneer de uitgever en de verificateurs verschillende entiteiten zijn (OAuth2, OpenID Connect, identiteitsfederatie). Het is het voorkeursalgoritme van de meeste publieke identiteitsproviders.
- ECDSA (ES256, ES384): asymmetrische handtekening op elliptische krommen. Zelfde logica als RSA (privésleutel om te ondertekenen, publieke sleutel om te verifiëren) maar met compactere sleutels en handtekeningen voor een equivalent beveiligingsniveau. Steeds vaker gebruikt in moderne architecturen.
Hoe de sleutel aanleveren
Het formaat van de verwachte sleutel hangt af van het algoritme dat in de header van de JWT is gedeclareerd:
- HS256, HS384, HS512: de sleutel is een geheime tekenreeks (string).
Het is het geheim gedeeld met de uitgever, vaak opgeslagen in een omgevingsvariabele zoals
JWT_SECRET. Geen bijzondere opmaak, gewoon de ruwe waarde. - RS256, RS384, RS512: de sleutel is een publieke RSA-sleutel in PEM-formaat,
die begint met
-----BEGIN PUBLIC KEY-----en eindigt met-----END PUBLIC KEY-----. Bewaar de regeleinden als zodanig, anders weigert OpenSSL deze te parsen. - ES256, ES384: de sleutel is een publieke ECDSA-sleutel in PEM-formaat, op de overeenkomstige kromme (P-256 voor ES256, P-384 voor ES384).
Voorbeeld van een verwachte publieke RSA-sleutel
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxe...
...vQIDAQAB
-----END PUBLIC KEY-----
Hoe werkt de verificatie?
Onze server reproduceert precies de bewerking die de uitgever heeft uitgevoerd:
- Hij scheidt de JWT in header, payload en handtekening.
- Hij voegt
base64url(header) + "." + base64url(payload)samen. - Voor HMAC berekent hij een HMAC-SHA-256/384/512 met uw geheime sleutel, en vergelijkt vervolgens met de
ontvangen handtekening via
hash_equals(vergelijking met constante tijd om temporele aanvallen te vermijden). - Voor RSA roept hij
openssl_verifyaan met uw publieke sleutel in PEM-formaat.
Gebruiksgevallen
- API-authenticatie-debug: u ontvangt een 401, controleer of uw token correct is ondertekend met de verwachte sleutel.
- Validatie van een token ontvangen van een provider: een partner (Auth0, Keycloak, Cognito, Okta) stuurt u JWT's ondertekend in RS256; u wilt bevestigen dat ze inderdaad van hem komen met zijn publieke sleutel.
- Beveiligingsaudit: verifiëren dat een service van derden zijn tokens correct ondertekent met een robuust algoritme, en niet in HS256 met een zwak geheim.
- Handmatige tests: verifiëren dat een door uw code gegenereerde JWT de verificatie passeert met de geleverde publieke sleutel.
- Snelle verificatie van een ontvangen token: tijdens de integratie van een SSO of een partner-API, in enkele seconden verifiëren dat de handtekening/sleutel-keten werkt voordat u ook maar één regel code schrijft.
Hoe u de tool gebruikt
- Plak de volledige JWT (de drie delen gescheiden door punten).
- Geef de sleutel aan die geschikt is voor het algoritme van de header:
- Voor HS256, HS384 of HS512, is de sleutel het geheim gedeelde
tekenreeks met de uitgever. Het is een vrije tekenreeks, vaak opgeslagen in een
omgevingsvariabele zoals
JWT_SECRET. - Voor RS256, RS384 of RS512, is de sleutel de publieke sleutel in PEM-formaat,
die begint met
-----BEGIN PUBLIC KEY-----en eindigt met-----END PUBLIC KEY-----.
- Voor HS256, HS384 of HS512, is de sleutel het geheim gedeelde
tekenreeks met de uitgever. Het is een vrije tekenreeks, vaak opgeslagen in een
omgevingsvariabele zoals
- Start de verificatie. De tool toont de status (geldig of ongeldig) en de gedecodeerde payload.
Veelvoorkomende valkuilen om te vermijden
- Algoritme "none": de spec staat
alg: nonetoe, wat betekent "geen handtekening". Een klassieke kwetsbaarheid bestaat uit het fabriceren van een token met deze header in de hoop dat de server het accepteert. Onze tool weigert systematisch tokens metalg: none. - HMAC vs RSA-verwarring (algorithm confusion): een aanvaller verandert het algoritme
RS256inHS256en ondertekent de payload met de publieke RSA-sleutel gebruikt als HMAC-geheim. Als de server het algoritme niet controleert, accepteert hij het token. Vergrendel altijd het verwachte algoritme aan de serverkant. - Hard-coded HMAC-geheimen in de code: een in een Git-repository gecommit geheim maakt alle tokenvertrouwen ongeldig. Bewaar geheimen in omgevingsvariabelen of een applicatie-kluis.
- Publieke sleutel vs privésleutel: om een in RSA of ECDSA ondertekende JWT te verifiëren, levert u de publieke sleutel, nooit de privé. De privé dient alleen om te ondertekenen en mag nooit uit de uitgever verlaten.
- Vervaldatum genegeerd: een geldige handtekening op een verlopen token mag
nooit worden geaccepteerd. Denk eraan om
expennbfte verifiëren. - Niet-gecontroleerde audience: een token bestemd voor API A zou niet geaccepteerd
mogen worden door API B. Verifieer de
aud-claim.
Temporele claims: exp en nbf
Naast de handtekening moet een geldige JWT ook zijn temporele beperkingen respecteren:
- exp (expiration): het token is niet meer geldig na deze datum.
- nbf (not before): het token is nog niet geldig voor deze datum.
Onze tool signaleert expliciet wanneer een token verlopen is of nog niet geldig, zelfs als zijn handtekening correct is. Dat is belangrijk: een geldige handtekening op een verlopen token mag nooit worden geaccepteerd in productie.
Verschil met onze JWT decoder
Onze JWT decoder beperkt zich tot het decoderen van de header- en payload-delen om ze leesbaar te maken. Hij voert geen handtekeningverificatie uit en vraagt geen sleutel. Gebruik deze om snel de inhoud van een token te inspecteren. Gebruik de JWT verifier (deze pagina) zodra u moet bewijzen dat een token authentiek is. Om een ondertekende JWT voor testdoeleinden te fabriceren, gebruik onze JWT builder.
Veelgestelde vragen
Waarom RS256 in plaats van HS256?
Met HS256 delen de uitgever en de verificateur hetzelfde geheim: elke verificateur kan dus tokens uitgeven. Het is beheersbaar wanneer men beide uiteinden controleert. Zodra men spreekt over een unieke identiteitsprovider met meerdere consumerende services, schakelt men over naar RS256: de uitgever behoudt de privésleutel, men distribueert de publieke sleutel aan alle API's die moeten verifiëren. Geen enkele consumerende API kan dan tokens smeden.
Hoe haal ik de publieke sleutel van een identiteitsprovider (IdP) op?
De meeste IdP's stellen een gestandaardiseerde JWKS-endpoint beschikbaar (bijvoorbeeld
https://voorbeeld.com/.well-known/jwks.json). Deze endpoint geeft een JSON terug met
de actieve publieke sleutels. U kunt de JWK-entry die overeenkomt met de kid
van de header van uw JWT converteren naar een PEM-sleutel via het openssl-commando of via een
JWKS-bibliotheek van uw stack (bijvoorbeeld jose-jwt, jwks-rsa).
Wat te doen als de verificatie mislukt?
Verifieer eerst het algoritme: een in HS256 ondertekend token wordt niet geverifieerd met een RSA-sleutel, en
omgekeerd. Verifieer vervolgens de sleutel: een teveel aan witruimte, een ontbrekend regeleinde
in een PEM-sleutel, of een HMAC-geheim dat licht verschilt van die gebruikt door de uitgever
volstaan om de verificatie te laten mislukken. Als de IdP een sleutelrotatie heeft uitgevoerd, kan uw
kid verwijzen naar een sleutel die u niet meer hebt.
Wat is JWKS?
JWKS (JSON Web Key Set, RFC 7517) is een JSON-formaat dat een set
publieke sleutels beschrijft. Elke sleutel wordt geïdentificeerd door een kid (key ID) en de te verifiëren JWT
verwijst naar deze kid in zijn header. Het mechanisme stelt de IdP in staat om zijn
sleutels te roteren zonder de verificateurs te breken: zij raadplegen gewoon de JWKS-endpoint om de
sleutel op te halen die overeenkomt met de kid van het ontvangen token.
Hoe genereer ik een RSA-sleutelpaar om mijn JWT's te ondertekenen?
Met OpenSSL: openssl genrsa -out private.pem 2048 vervolgens
openssl rsa -in private.pem -pubout -out public.pem. De privésleutel ondertekent aan de
uitgeverskant, de publieke sleutel verifieert aan de consumentenkant. Voor nieuwe services, verkies 3072 of
4096 bits.
Moet de JWT versleuteld worden naast ondertekend (JWE)?
Een ondertekende JWT (JWS) garandeert de integriteit en authenticiteit, maar de payload blijft leesbaar voor iedereen die hem ophaalt. Als het token gevoelige gegevens bevat (interne identifiers, gedetailleerde rechten, persoonsgegevens), overweeg dan het JWE-formaat (JSON Web Encryption) dat de payload versleutelt naast deze te ondertekenen.
Voorbeeldverzoek
curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
-H "Content-Type: application/json" \
-d '{"token":"...","key":"..."}'
Invoerschema
| Veld | Type | Vereist | Standaard |
|---|---|---|---|
token |
text | ✓ | – |
key |
text | ✓ | – |
Endpoints
GET https://cdrn.fr/api/v1/tools- toont alle beschikbare toolsGET https://cdrn.fr/api/v1/tools/jwt-verifier- geeft het schema van deze tool terugPOST https://cdrn.fr/api/v1/tools/jwt-verifier/execute- voert deze tool uit met een JSON-payload