Verificarea semnăturii unui JSON Web Token (JWT)
- Panou de control
- Documentație
- API
De ce să verifici semnătura unui JWT?
Un JSON Web Token (JWT) se descompune în trei părți separate de puncte:
header.payload.signature. A decoda un JWT constă simplu în a citi primele două
părți (care sunt Base64URL). Oricine poate face acest lucru, și oricine poate fabrica
un JWT cu payload-ul ales. Ceea ce face un JWT demn de încredere este doar
semnătura: fără verificare, a accepta un JWT echivalează cu a lăsa să intre la tine orice persoană care
pretinde că este cineva, fără să ceri o piesă de identitate.
Acest instrument verifică semnătura a unui JWT plecând de la o cheie. Nu se mulțumește să decodeze: recalculează semnătura plecând de la header, payload și cheia ta, apoi o compară cu semnătura token-ului. Dacă cele două concordă, token-ul este autentic. Altfel, a fost forjat, modificat, sau semnat cu altă cheie.
Verificarea este piatra de temelie a oricărei arhitecturi care utilizează JWT-uri pentru
autentificare sau autorizare: fără semnătură validă, payload-ul poate minți.
Un atacator care ar modifica "role":"user" în "role":"admin" nu ar avea nicio
dificultate să o facă dacă serverul ar verifica doar formatul token-ului și nu semnătura sa.
Algoritmi curenți
Specificația JWT (RFC 7518, JSON Web Algorithms) definește mai multe familii de algoritmi. Iată cele mai utilizate în producție:
- HMAC (HS256, HS384, HS512): semnătură simetrică pe bază de HMAC-SHA. Aceeași cheie secretă servește la semnare și la verificare. Simplu de pus în loc, performant, dar orice parte capabilă să verifice token-ul este de asemenea capabilă să emită. Adaptat scenariilor unde emitentul și verificatorul sunt aceeași echipă sau același serviciu.
- RSA (RS256, RS384, RS512): semnătură asimetrică. Cheia privată semnează, cheia publică verifică. Ideal când emitentul și verificatorii sunt entități distincte (OAuth2, OpenID Connect, federație de identitate). Este algoritmul privilegiat de majoritatea furnizorilor de identitate publici.
- ECDSA (ES256, ES384): semnătură asimetrică pe curbe eliptice. Aceeași logică ca RSA (cheie privată pentru a semna, cheie publică pentru a verifica) dar cu chei și semnături mai compacte pentru un nivel de securitate echivalent. Din ce în ce mai răspândit în arhitecturile moderne.
Cum să furnizezi cheia
Formatul cheii așteptate depinde de algoritmul declarat în header-ul JWT-ului:
- HS256, HS384, HS512: cheia este un șir secret (string).
Este secretul partajat cu emitentul, adesea stocat într-o variabilă de mediu precum
JWT_SECRET. Nicio punere în formă particulară, doar valoarea brută. - RS256, RS384, RS512: cheia este o cheie publică RSA în format PEM,
care începe cu
-----BEGIN PUBLIC KEY-----și se termină cu-----END PUBLIC KEY-----. Păstrează returnurile la linie ca atare, altfel OpenSSL refuză să o parseze. - ES256, ES384: cheia este o cheie publică ECDSA în format PEM, pe curba corespunzătoare (P-256 pentru ES256, P-384 pentru ES384).
Exemplu de cheie publică RSA așteptată
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxe...
...vQIDAQAB
-----END PUBLIC KEY-----
Cum funcționează verificarea?
Serverul nostru reproduce exact operația pe care a făcut-o emitentul:
- Separă JWT-ul în header, payload și semnătură.
- Concatenează
base64url(header) + "." + base64url(payload). - Pentru HMAC, calculează un HMAC-SHA-256/384/512 cu cheia ta secretă, apoi compară cu
semnătura primită prin
hash_equals(comparație în timp constant pentru a evita atacurile temporale). - Pentru RSA, apelează
openssl_verifycu cheia ta publică în format PEM.
Cazuri de utilizare
- Debug de autentificare API: primești un 401, verifici dacă token-ul tău este într-adevăr semnat cu cheia așteptată.
- Validare a unui token primit de la un furnizor: un partener (Auth0, Keycloak, Cognito, Okta) îți trimite JWT-uri semnate în RS256; vrei să confirmi că provin într-adevăr de la el cu cheia sa publică.
- Audit de securitate: a verifica dacă un serviciu terț își semnează corect token-urile cu un algoritm robust, și nu în HS256 cu un secret slab.
- Teste manuale: a verifica dacă un JWT generat de codul tău trece bine verificarea cu cheia publică furnizată.
- Verificare rapidă a unui token primit: în timpul integrării unui SSO sau a unui API partener, a verifica în câteva secunde că lanțul semnătură/cheie funcționează înainte de a scrie cea mai mică linie de cod.
Cum să utilizezi instrumentul
- Lipește JWT-ul complet (cele trei părți separate de puncte).
- Indică cheia adaptată algoritmului header-ului:
- Pentru HS256, HS384 sau HS512, cheia este șirul secret
partajat cu emitentul. Este un șir liber, adesea stocat într-o
variabilă de mediu precum
JWT_SECRET. - Pentru RS256, RS384 sau RS512, cheia este cheia publică în format
PEM, care începe cu
-----BEGIN PUBLIC KEY-----și se termină cu-----END PUBLIC KEY-----.
- Pentru HS256, HS384 sau HS512, cheia este șirul secret
partajat cu emitentul. Este un șir liber, adesea stocat într-o
variabilă de mediu precum
- Lansează verificarea. Instrumentul afișează statutul (valid sau invalid) și payload-ul decodat.
Capcane curente de evitat
- Algoritmul "none": specificația autorizează
alg: none, care înseamnă "fără semnătură". O vulnerabilitate clasică constă în a fabrica un token cu acest header sperând ca serverul să-l accepte. Instrumentul nostru respinge sistematic token-urile cualg: none. - Confuzie HMAC vs RSA (algorithm confusion): un atacator schimbă algoritmul
RS256înHS256și semnează payload-ul cu cheia publică RSA utilizată ca secret HMAC. Dacă serverul nu controlează algoritmul, acceptă token-ul. Întotdeauna blochează algoritmul așteptat pe partea serverului. - Secrete HMAC în clar în cod: un secret commitat într-un depozit Git face toată încrederea token-urilor caducă. Stochează secretele în variabile de mediu sau într-un seif aplicativ.
- Cheie publică vs cheie privată: pentru a verifica un JWT semnat în RSA sau ECDSA, se furnizează cheia publică, niciodată privata. Privata servește doar la semnare și nu trebuie niciodată să iasă de la emitent.
- Expirare ignorată: o semnătură validă pe un token expirat nu trebuie
niciodată să fie acceptată. Gândește-te să verifici
expșinbf. - Audiență necontrolată: un token destinat API-ului A nu ar trebui să fie acceptat
de API-ul B. Verifică claim-ul
aud.
Claim-uri temporale: exp și nbf
Dincolo de semnătură, un JWT valid trebuie să respecte și constrângerile sale temporale:
- exp (expirare): token-ul nu mai este valid după această dată.
- nbf (not before): token-ul nu este încă valid înainte de această dată.
Instrumentul nostru semnalează explicit când un token este expirat sau nu încă valid, chiar dacă semnătura sa este corectă. Este important: o semnătură validă pe un token expirat nu trebuie niciodată acceptată în producție.
Diferența cu JWT decoder-ul nostru
JWT decoder-ul nostru se mulțumește să decodeze părțile header și payload pentru a le face lizibile. Nu efectuează nicio verificare de semnătură și nu cere o cheie. Utilizează-l pentru a inspecta rapid conținutul unui token. Utilizează JWT verifier-ul (această pagină) imediat ce ai nevoie să dovedești că un token este autentic. Pentru a fabrica un JWT semnat în scop de test, utilizează JWT builder-ul nostru.
Întrebări frecvente
De ce RS256 în loc de HS256?
Cu HS256, emitentul și verificatorul partajează același secret: orice verificator poate deci să emită token-uri. Este gestionabil când se controlează ambele capete. Imediat ce se vorbește de un furnizor de identitate unic cu mai multe servicii consumatoare, se basculează în RS256: emitentul păstrează cheia privată, se distribuie cheia publică tuturor API-urilor care trebuie să verifice. Niciun API consumator nu poate atunci forja token-uri.
Cum să recuperez cheia publică a unui furnizor de identitate (IdP)?
Majoritatea IdP-urilor expun un endpoint JWKS standardizat (de exemplu
https://exemplu.com/.well-known/jwks.json). Acest endpoint returnează un JSON conținând
cheile publice active. Poți converti intrarea JWK care corespunde kid-ului
header-ului JWT-ului tău în cheie PEM prin comanda openssl sau printr-o bibliotecă
JWKS a stack-ului tău (de exemplu jose-jwt, jwks-rsa).
Ce să fac dacă verify eșuează?
Verifică mai întâi algoritmul: un token semnat în HS256 nu se verifică cu o cheie RSA, și
invers. Verifică apoi cheia: un caracter alb în plus, un retur la linie lipsă
într-o cheie PEM, sau un secret HMAC ușor diferit de cel utilizat de emitent
sunt suficiente pentru a face verificarea să eșueze. Dacă IdP-ul a efectuat o rotație de cheie,
kid-ul tău poate indica spre o cheie pe care nu o mai ai.
JWKS, ce este?
JWKS (JSON Web Key Set, RFC 7517) este un format JSON care descrie un set de
chei publice. Fiecare cheie este identificată printr-un kid (key ID) iar JWT-ul de verificat
referențiază acest kid în header-ul său. Mecanismul permite IdP-ului să-și rotească
cheile fără a strica verificatorii: aceștia interoghează simplu endpoint-ul JWKS pentru a recupera
cheia corespunzătoare kid-ului token-ului primit.
Cum să generez o pereche de chei RSA pentru a-mi semna JWT-urile?
Cu OpenSSL: openssl genrsa -out private.pem 2048 apoi
openssl rsa -in private.pem -pubout -out public.pem. Cheia privată semnează pe partea
emitentului, cheia publică verifică pe partea consumatorului. Pentru noi servicii, preferă 3072 sau
4096 biți.
Trebuie să criptez JWT-ul pe lângă a-l semna (JWE)?
Un JWT semnat (JWS) garantează integritatea și autenticitatea, dar payload-ul rămâne lizibil de oricine îl recuperează. Dacă token-ul conține date sensibile (identificatori interni, drepturi detaliate, date personale), ia în considerare formatul JWE (JSON Web Encryption) care criptează payload-ul pe lângă a-l semna.
Exemplu de cerere
curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
-H "Content-Type: application/json" \
-d '{"token":"...","key":"..."}'
Schema de intrare
| Câmp | Tip | Obligatoriu | Implicit |
|---|---|---|---|
token |
text | ✓ | – |
key |
text | ✓ | – |
Puncte de acces
GET https://cdrn.fr/api/v1/tools- listează toate instrumentele disponibileGET https://cdrn.fr/api/v1/tools/jwt-verifier- obține schema acestui instrumentPOST https://cdrn.fr/api/v1/tools/jwt-verifier/execute- execută acest instrument cu un payload JSON