Varmenna JSON Web Token (JWT) -allekirjoitus

varmentaa JWT:n (HS256, HS384, HS512, RS256, RS384, RS512) allekirjoituksen salaisuudesta tai julkisesta avaimesta, ja tarkastaa sen claimit
HS256 / HS384 / HS512 -algoritmeille: salainen merkkijono. RS256 / RS384 / RS512 -algoritmeille: julkinen avain PEM-muodossa.

Miksi JWT-allekirjoitus on vahvistettava?

JSON Web Token (JWT) jakautuu kolmeen pisteillä erotettuun osaan : header.payload.signature. JWT-tokenin dekoodaus on vain kahden ensimmäisen osan (jotka ovat Base64URL-muodossa) lukemista. Kuka tahansa voi tehdä sen, ja kuka tahansa voi valmistaa JWT-tokenin millä tahansa hyötykuormalla. Vain allekirjoitus tekee JWT-tokenista luotettavan : ilman vahvistusta JWT:n hyväksyminen on kuin päästäisit kotiisi kenet tahansa, joka väittää olevansa joku, kysymättä henkilöllisyystodistusta.

Tämä työkalu vahvistaa JWT-allekirjoituksen avaimen perusteella. Se ei vain dekoodaa : se laskee allekirjoituksen uudelleen otsikon, hyötykuorman ja avaimesi perusteella, ja vertaa sitä tokenin allekirjoitukseen. Jos ne täsmäävät, token on aito. Muussa tapauksessa se on väärennetty, sitä on muutettu tai se on allekirjoitettu eri avaimella.

Vahvistus on kaiken JWT-pohjaisen todennus- tai valtuutusarkkitehtuurin kulmakivi : ilman pätevää allekirjoitusta hyötykuorma voi valehdella. Hyökkääjä voisi helposti muuttaa arvon "role":"user" arvoksi "role":"admin", jos palvelin tarkistaisi vain tokenin muodon eikä sen allekirjoitusta.

Yleiset algoritmit

JWT-määrittely (RFC 7518, JSON Web Algorithms) määrittelee useita algoritmiluokkia. Tässä ovat tuotannossa yleisimmin käytetyt :

  • HMAC (HS256, HS384, HS512) : symmetrinen HMAC-SHA-pohjainen allekirjoitus. Samaa salaista avainta käytetään sekä allekirjoittamiseen että vahvistamiseen. Helppo toteuttaa ja suorituskykyinen, mutta jokainen osapuoli, joka voi vahvistaa tokenin, voi myös myöntää niitä. Soveltuu tilanteisiin, joissa lähettäjä ja tarkistaja ovat sama tiimi tai palvelu.
  • RSA (RS256, RS384, RS512) : epäsymmetrinen allekirjoitus. Yksityinen avain allekirjoittaa, julkinen avain vahvistaa. Ihanteellinen, kun lähettäjä ja tarkistajat ovat eri tahoja (OAuth2, OpenID Connect, identiteettifiteraatio). Tämä on useimpien julkisten identiteettipalvelun tarjoajien suosima algoritmi.
  • ECDSA (ES256, ES384) : epäsymmetrinen allekirjoitus elliptisillä käyrillä. Sama logiikka kuin RSA:ssa (yksityinen avain allekirjoitukseen, julkinen vahvistukseen), mutta lyhyemmillä avaimilla ja allekirjoituksilla saman tietoturvatason saavuttamiseksi. Yhä yleisempi nykyaikaisissa arkkitehtuureissa.

Miten avain annetaan

Odotetun avaimen muoto riippuu JWT-otsikossa ilmoitetusta algoritmista :

  • HS256, HS384, HS512 : avain on salainen merkkijono (string). Se on lähettäjän kanssa jaettu salaisuus, joka on usein tallennettu ympäristömuuttujaan kuten JWT_SECRET. Ei erityistä muotoilua, vain raaka arvo.
  • RS256, RS384, RS512 : avain on PEM-muotoinen julkinen RSA-avain, joka alkaa rivillä -----BEGIN PUBLIC KEY----- ja päättyy riviin -----END PUBLIC KEY-----. Säilytä rivinvaihdot sellaisinaan, muuten OpenSSL ei pysty jäsentämään sitä.
  • ES256, ES384 : avain on PEM-muotoinen julkinen ECDSA-avain vastaavalla käyrällä (P-256 ES256:lle, P-384 ES384:lle).

Esimerkki odotetusta julkisesta RSA-avaimesta

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxe...
...vQIDAQAB
-----END PUBLIC KEY-----

Miten vahvistus toimii?

Palvelimemme toistaa täsmälleen saman toimenpiteen kuin lähettäjä :

  1. Se jakaa JWT-tokenin otsikkoon, hyötykuormaan ja allekirjoitukseen.
  2. Se yhdistää osat base64url(header) + "." + base64url(payload).
  3. HMAC-algoritmeille se laskee HMAC-SHA-256/384/512-tiivisteen salaisella avaimellasi ja vertaa sitä vastaanotettuun allekirjoitukseen käyttämällä hash_equals-funktiota (vakiomuotoinen vertailu ajoitushyökkäysten estämiseksi).
  4. RSA-algoritmeille se kutsuu openssl_verify-funktiota PEM-muotoisella julkisella avaimellasi.

Käyttötapaukset

  • API-todennuksen debuggaus : saat 401-virheen, tarkista onko tokenisi todella allekirjoitettu odotetulla avaimella.
  • Toimittajalta saadun tokenin vahvistaminen : kumppani (Auth0, Keycloak, Cognito, Okta) lähettää sinulle RS256-allekirjoitettuja JWT-tokeneita; haluat varmistaa julkisen avaimen avulla, että ne ovat todella häneltä.
  • Tietoturva-auditointi : varmista, että kolmannen osapuolen palvelu allekirjoittaa tokeninsa oikein vankalla algoritmilla eikä HS256:lla ja heikolla salaisuudella.
  • Manuaaliset testit : varmista, että koodisi generoima JWT läpäisee vahvistuksen annetulla julkisella avaimella.
  • Vastaanotetun tokenin nopea tarkistus : SSO- tai kumppani-API-integraation aikana voit tarkistaa muutamassa sekunnissa, että allekirjoitus/avain-ketju toimii ennen kuin kirjoitat riviäkään koodia.

Työkalun käyttöohjeet

  1. Liitä koko JWT (kolme pistellä erotettua osaa).
  2. Ilmoita otsikon algoritmiin sopiva avain :
    • Algoritmeille HS256, HS384 tai HS512 avain on lähettäjän kanssa jaettu salainen merkkijono. Se on vapaamuotoinen merkkijono, joka on usein tallennettu ympäristömuuttujaan kuten JWT_SECRET.
    • Algoritmeille RS256, RS384 tai RS512 avain on PEM-muotoinen julkinen avain, joka alkaa rivillä -----BEGIN PUBLIC KEY----- ja päättyy riviin -----END PUBLIC KEY-----.
  3. Käynnistä vahvistus. Työkalu näyttää tilan (pätevä tai virheellinen) ja dekoodatun hyötykuorman.

Yleisiä vältettäviä sudenkuoppia

  • Algoritmi "none" : spesifikaatio sallii alg: none, joka tarkoittaa "ei allekirjoitusta". Klassinen haavoittuvuus on luoda token tällä otsakkeella toivoen, että palvelin hyväksyy sen. Työkalumme hylkää aina tokenit, joissa on alg: none.
  • HMAC vs RSA -sekaannus (algorithm confusion) : hyökkääjä muuttaa algoritmin RS256 muotoon HS256 ja allekirjoittaa hyötykuorman RSA-julkisella avaimella, jota käytetään HMAC-salaisuutena. Jos palvelin ei tarkista algoritmia, se hyväksyy tokenin. Lukitse aina odotettu algoritmi palvelimen puolella.
  • Koodiin kovakoodatut HMAC-salaisuudet : Git-repositorioon tallennettu salaisuus tekee kaikista tokeneista epäluotettavia. Tallenna salaisuudet ympäristömuuttujiin tai sovelluksen salaisuuksien hallintaan.
  • Julkinen avain vs yksityinen avain : RSA- tai ECDSA-allekirjoitetun JWT:n vahvistamiseksi annetaan julkinen avain, ei koskaan yksityistä. Yksityinen avain on vain allekirjoittamista varten, eikä se saa koskaan poistua lähettäjältä.
  • Vanhentumisen huomiotta jättäminen : vanhentuneen tokenin kelvollista allekirjoitusta ei saa koskaan hyväksyä. Muista tarkistaa exp ja nbf.
  • Valvomaton yleisö (audience) : API A:lle tarkoitettua tokenia ei pitäisi hyväksyä API B:ssä. Tarkista aud-väite.

Aikaleimaväitteet: exp ja nbf

Allekirjoituksen lisäksi kelvollisen JWT:n on noudatettava myös aikaviiveitään :

  • exp (expiration) : token ei ole enää voimassa tämän päivämäärän jälkeen.
  • nbf (not before) : token ei ole vielä voimassa ennen tätä päivämäärää.

Työkalumme ilmoittaa nimenomaisesti, kun token on vanhentunut tai ei vielä voimassa, vaikka sen allekirjoitus olisi oikea. Tämä on tärkeää : vanhentuneen tokenin kelvollista allekirjoitusta ei saa koskaan hyväksyä tuotannossa.

Ero JWT-dekooderiimme

Meidän JWT-dekooderi vain dekoodaa otsikko- ja hyötykuorma-osat niiden lukemiseksi. Se ei suorita mitään vahvistusta allekirjoitukselle eikä pyydä avainta. Käytä sitä tokenin sisällön nopeaan tarkasteluun. Käytä JWT verifieriä (tämä sivu), kun haluat todistaa tokenin olevan aito. Jos haluat luoda allekirjoitetun JWT:n testausta varten, käytä meidän JWT builderiamme.

Usein kysytyt kysymykset

Miksi RS256 eikä HS256 ?

HS256:ssa lähettäjä ja vahvistaja jakavat saman salaisuuden : kuka tahansa vahvistaja voi siis luoda tokeneita. Tämä on hallittavissa, kun molemmat päät ovat hallinnassa. Heti kun kyseessä on yksi identiteetintarjoaja useilla kuluttajapalveluilla, siirrytään RS256:een : lähettäjä pitää yksityisen avaimen, ja julkinen avain jaetaan kaikille API:ille, joiden on vahvistettava tokenit. Mikään kuluttava API ei voi tällöin väärentää tokeneita.

Miten haen identiteetintarjoajan (IdP) julkisen avaimen ?

Useimmat IdP:t tarjoavat standardoidun JWKS-päätepisteen (esimerkiksi https://esimerkki.com/.well-known/jwks.json). Tämä päätepiste palauttaa JSON-tiedoston, joka sisältää aktiiviset julkiset avaimet. Voit muuntaa JWT-otsikon kid-tunnusta vastaavan JWK-merkinnän PEM-avaimeksi openssl-komennolla tai käyttämällä pinoasi vastaavaa JWKS-kirjastoa (esimerkiksi jose-jwt, jwks-rsa).

Mitä tehdä, jos vahvistus epäonnistuu ?

Tarkista ensin algoritmi : HS256:lla allekirjoitettua tokenia ei vahvisteta RSA-avaimella, ja päinvastoin. Tarkista sitten avain : yksi ylimääräinen välilyönti, puuttuva rivinvaihto PEM-avaimessa tai hieman erilainen HMAC-salaisuus kuin lähettäjän käyttämä riittävät vahvistuksen epäonnistumiseen. Jos IdP on kierrättänyt avaimen, kid-tunnuksesi voi osoittaa avaimeen, jota sinulla ei enää ole.

JWKS, mikä se on ?

JWKS (JSON Web Key Set, RFC 7517) on JSON-muoto, joka kuvaa joukon julkisia avaimia. Jokainen avain tunnistetaan kid-tunnuksella (key ID), ja vahvistettava JWT viittaa tähän kid-tunnukseen otsikossaan. Mekanismi mahdollistaa IdP:n avainten kierrättämisen rikkomatta vahvistajia : ne vain kysyvät JWKS-päätepisteestä avainta, joka vastaa saadun tokenin kid-tunnusta.

Miten luon RSA-avainparin JWT:iden allekirjoittamiseen ?

OpenSSL:llä : openssl genrsa -out private.pem 2048 ja sitten openssl rsa -in private.pem -pubout -out public.pem. Yksityinen avain allekirjoittaa lähettäjän puolella, julkinen avain vahvistaa kuluttajan puolella. Uusille palveluille suositellaan 3072 tai 4096 bittiä.

Pitääkö JWT myös salata allekirjoittamisen lisäksi (JWE) ?

Allekirjoitettu JWT (JWS) takaa eheydyn ja aitouden, mutta hyötykuorma on silti luettavissa kenelle tahansa, joka saa sen käsiinsä. Jos token sisältää arkaluonteisia tietoja (sisäiset tunnukset, yksityiskohtaiset oikeudet, henkilötiedot), harkitse JWE-muotoa (JSON Web Encryption), joka salaa hyötykuorman allekirjoittamisen lisäksi.

Pyyntöesimerkki

curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
  -H "Content-Type: application/json" \
  -d '{"token":"...","key":"..."}'

Syöteskeema

Kenttä Tyyppi Pakollinen Oletus
token text
key text

Päätepisteet

  • GET https://cdrn.fr/api/v1/tools - listaa kaikki saatavilla olevat työkalut
  • GET https://cdrn.fr/api/v1/tools/jwt-verifier - hakee tämän työkalun skeeman
  • POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute - suorittaa tämän työkalun JSON-payloadilla