Dekoodaa JSON Web Token (JWT)
- Hallintapaneeli
- Dokumentaatio
- API
Mikä on JWT (JSON Web Token)?
JSON Web Token, lyhennettynä JWT (lausutaan "jot"), on RFC 7519 -standardin mukainen kompakti muoto, joka mahdollistaa väittämien (claims) siirtämisen kahden osapuolen välillä. JWT eli JWT-tokeni on nykyään hallitseva muoto todennetun identiteetin välittämiseen HTTP-rajapinnassa. JWT koostuu ASCII-merkkijonosta, jossa on kolme pisteillä erotettua osaa :
header.payload.signature
Jokainen osa on koodattu Base64URL-muodossa, joka on Base64-muunnos ilman
=-täytettä ja jossa + korvataan merkillä - ja /
merkillä _, jotta se voi kulkea URL-osoitteessa tai HTTP-otsikossa ilman
lisämerkistömuunnoksia.
Tärkeää: JWT-tokenia EI ole salattu. Standardi JWT-muoto (JWS) on simplement allekirjoitettu : allekirjoitus takaa sisällön eheyden, mutta ei luottamuksellisuutta. Kuka tahansa voi dekoodata JWT-hyötykuorman yksinkertaisella käänteisellä Base64URL-muunnoksella, kuten tämä verkossa toimiva jwt decode -työkalu tekee.
JWT-tokenin rakenne
JSON Web Token koostuu kolmesta selkeästä osasta, joista jokaisella on tietty rooli todennusmekanismissa :
1. Otsikko (Header)
Otsikko on JSON-objekti, joka kuvailee, miten token on allekirjoitettu. Se sisältää vähintään :
alg(algoritmi) : käytetty allekirjoitusalgoritmi. Tyypillisiä arvoja :HS256,RS256,ES256,EdDSA.typ(tyyppi) : tokenin tyyppi, lähes aina"JWT".kid(avaimen ID) : valinnainen, tunnistaa mitä avainta on käytettävä allekirjoituksen vahvistamiseen. Pratique en présence d'un parc de clés en rotation (JWKS).
2. Hyötykuorma (Payload)
Hyötykuorma sisältää väittämät (claims), eli lähettäjän antamat tiedot käyttäjästä tai istunnosta. RFC 7519 määrittelee seitsemän vakioväittämää (registered claims) :
iss(liikkeeseenlaskija) : kuka on myöntänyt tokenin, esimerkiksi"https://accounts.google.com".sub(kohde) : kenelle token kuuluu, käytännössä käyttäjätunnus.aud(vastaanottaja) : kenelle token on tarkoitettu. Estää sen, että API A:lle myönnettyä tokenia käytettäisiin API B:ssä.exp(vanhenemisaika) : Unix-aikaleima, jonka jälkeen token ei ole enää voimassa.nbf(ei ennen) : aikaleima, jota ennen token ei ole vielä aktiivinen.iat(myöntämisaika) : tokenin myöntämisajankohta.jti(JWT ID) : tokenin yksilöllinen tunniste, jota käytetään peruutuksiin ja toistohyökkäysten estämiseen.
Näiden vakioväittämien lisäksi mukaan lisätään yleensä sovelluskohtaisia
mukautettuja väittämiä (roles, scope, tenant_id,
email, permissions...).
3. Allekirjoitus (Signature)
Allekirjoitus on kryptografinen tiiviste, joka lasketaan muodosta
base64url(header) + "." + base64url(payload) avaimen avulla. Se todistaa, ettei
kukaan ole muuttanut otsikkoa tai hyötykuormaa myöntämisen jälkeen. Yleisimmät algoritmit :
- HS256 / HS384 / HS512 : symmetrinen HMAC-SHA-allekirjoitus. Lähettäjän ja tarkistajan välinen jaettu salainen avain. Yksinkertainen, mutta ei sovellu, jos kuluttajia on useita.
- RS256 / RS384 / RS512 : epäsymmetrinen RSA-allekirjoitus. Lähettäjä allekirjoittaa yksityisellä avaimellaan, kuka tahansa kuluttaja voi tarkistaa sen vastaavalla julkisella avaimella. Tosiasiallinen standardi OAuth2- ja OpenID Connect -järjestelmissä.
- ES256 / ES384 / ES512 : epäsymmetrinen ECDSA-allekirjoitus. Samat ominaisuudet kuin RS256:ssa, mutta huomattavasti lyhyemmät avaimet ja allekirjoitukset.
- EdDSA (Ed25519) : nykyaikainen, nopea ja kompakti epäsymmetrinen allekirjoitus.
Vielä kerran : allekirjoitus suojaa eheyttä, ei luottamuksellisuutta. Hyötykuorma on edelleen kenen tahansa tokenin haltijan luettavissa.
Miksi dekoodata JWT?
Toiminto JWT-tokenin dekoodaus vastaa useisiin kehittäjän tai tietoturvainsinöörin käytännön tarpeisiin :
- API-todennuksen debuggaus : rajapintasi palauttaa 401- tai 403-virheen,
ja haluat nähdä, mitä hyötykuormassa todella on (
sub,scope,roles,exp) arvailun sijaan. - Väittämien tarkistaminen : varmistaa, että token sisältää odotetun
väittämän (esimerkiksi
tenant_idtaipermissions) ennen kuin etsit muualta valtuutusketjusta. - Vanhenemisajan lukeminen : muuntaa
exp-aikaleima ihmisen luettavaan muotoon varmistaaksesi, että token on todella vanhentunut, tai päinvastoin, että sen pitäisi edelleen olla voimassa. - Tietoturva-auditointi : varmistaa, ettei kolmannen osapuolen palvelu vuoda arkaluonteisia tietoja hyötykuormassa (sähköpostit, sisäiset tunnisteet, henkilötiedot).
- Koulutus ja ymmärrys : nähdä käytännössä, miltä OAuth-palveluntarjoajalta (Google, Auth0, Keycloak, AWS Cognito) tuleva JSON Web Token näyttää ymmärtääksesi mekanismin ilman dokumentaatioon syventymistä.
- Julkisten tokeneiden tarkastelu : tarkastella lokeista, evästeistä tai kaapatusta OAuth-liikenteestä löytynyttä JWT-tokenia.
Dekooderi vs. vahvistaja : kriittinen ero
Nämä kaksi toimintoa vaikuttavat läheisiltä, mutta ne ovat täysin erilaisia tietoturvatakuun kannalta :
- JWT-tokenin dekoodaus tarkoittaa merkkijonon jakamista
.-merkkien kohdalta ja käänteisen Base64URL-muunnoksen soveltamista kahteen ensimmäiseen osaan. Se on pelkkää lukemista, johon pystyy mikä tahansa kolmen rivin skripti. Allekirjoituksen vahvistusta ei tehdä. - JWT-tokenin vahvistaminen tarkoittaa allekirjoituksen laskemista uudelleen otsikon, hyötykuorman ja avaimen perusteella, ja tuloksen vertaamista tokenissa olevaan allekirjoitukseen. Tämä takaa, ettei tokenia ole väärennetty.
Käytännön johtopäätös : dekoodaus ei tarkoita luottamusta. Ennen kuin allekirjoitus on vahvistettu oikealla avaimella, hyötykuorman sisältö voi olla täysin keksittyä. Luottamuksen varmistamiseksi käytä JWT-vahvistajaamme.
Miten sitä käytetään
- Hanki tarkistettava JWT, esimerkiksi
Authorization: Bearer <jwt>-otsikosta, istuntoevästeestä, selaimenlocalStorage-muistista tai sovelluslokista. - Liitä koko merkkijono syöttökenttään. Kolmen osan on pysyttävä pisteillä erotettuina.
- Työkalu näyttää välittömästi dekoodatun otsikon muotoiltuna JSON-muotona, sisältäen algoritmin ja tyypin.
- Sen jälkeen hyötykuorma dekoodataan ja näytetään. Näet siinä kaikki vakio- ja mukautetut väittämät.
- Työkalu ilmoittaa myös allekirjoitustiedot (ilmoitettu algoritmi, pituus) niitä kuitenkaan vahvistamatta.
- Varmistaaksesi, ettei tokenia ole väärennetty, siirry JWT-vahvistajaamme ja käytä odotettua julkista avainta tai salaisuutta.
Kaikki dekoodaus tapahtuu selaimessasi JavaScriptillä : tokeniasi ei koskaan lähetetä palvelimillemme.
JWT ja tietoturva : vältettävät sudenkuopat
ÄLÄ KOSKAAN tallenna arkaluonteisia tietoja allekirjoitetun JWT:n hyötykuormaan.
Salasanat, luottokorttinumerot, terveystiedot, rajapintojen salaisuudet, kriittiset sisäiset tunnisteet : kaikki hyötykuormassa oleva on kenen tahansa tokenin haltijan luettavissa, mukaan lukien käyttäjä itse selaimen kehitystyökalujen kautta. Allekirjoitus ei piilota mitään, se vain todistaa, että lähettäjä on se, joka hän väittää olevansa.
Muutamia kultaisia sääntöjä JWT:n käyttöön tuotannossa :
- Vahvista allekirjoitus aina palvelinpuolella ennen kuin myönnät mitään oikeuksia. JWT-vahvistajamme havainnollistaa juuri tätä toimintoa.
- Käytä mieluummin RS256- tai ES256-algoritmia HS256:n sijaan julkisissa rajapinnoissa. Epäsymmetrinen allekirjoitus välttää salaisuuden jakamisen lähettäjän ja jokaisen kuluttajan välillä.
- Noudata aina väittämää
exp. JWT ilman vanhenemisaikaa tai liian pitkällä vanhenemisajalla on aikapommi vuodon sattuessa. - Vahvista
issjaaudpalvelinpuolella välttääksesi sen, että toiselle palvelulle myönnetty laillinen token hyväksyttäisiin vahingossa. - Hylkää
alg: "none"tarkistusvaiheessa. Tämä on klassinen haavoittuvuus, jonka avulla hyökkääjä voi väärentää minkä tahansa hyötykuorman. - Pidä elinkaaret lyhyinä (esimerkiksi 15 minuuttia) ja käytä niitä yhdessä pidemmän, mutta palvelinpuolella peruutettavissa olevan päivitystokenin (refresh token) kanssa.
Esimerkki dekoodatusta JWT-tokenista
Tässä on tyypillinen JWT :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiSm9obiIsImlhdCI6MTUxNjIzOTAyMn0.jrU9j8LZcRK2_BZjqXjU7lEpJbkqmXfTQIu9vT45j-I
Dekoodattuna sen sisältö on seuraava :
// Otsikko
{
"alg": "HS256",
"typ": "JWT"
}
// Hyötykuorma
{
"sub": "123",
"name": "John",
"iat": 1516239022
}
// Allekirjoitus (binäärinen, koodattu Base64URL-muodossa)
HMACSHA256(
base64url(header) + "." + base64url(payload),
secret
)
Mistä löytää kopioitava JWT?
Käytännössä dekoodattava JWT on yleensä peräisin jostakin näistä paikoista :
- HTTP-eväste : avaa kehitystyökalut (F12), välilehti Application tai
Storage, ja sieltä Cookies. Etsi eväste, jonka nimi on
access_token,jwt,sessiontai vastaava. localStorage/sessionStorage: sama paneeli, osio Local Storage. Monet SPA-sovellukset tallentavat tokeninsa tänne avaimellatokentaiauth.Authorization-otsikko : välilehti Network, valitse rajapintapyyntö, lue otsikkoAuthorization: Bearer <jwt>. Kopioi vain osa, joka tulee sananBearerjälkeen.- Palvelinloki : JWT saattaa joskus näkyä yhdyskäytävän tai käänteisen välityspalvelimen lokeissa (vältettävä tuotannossa, mutta hyödyllinen debugauksessa).
Usein kysytyt kysymykset
Onko JWT salattu vai selkokielinen?
Allekirjoitettu JWT (JWS-muoto) on vain Base64URL-koodattu, ei salattu. Kuka tahansa tokenin sieppaava voi lukea hyötykuorman sekunneissa. Jos sinun on siirrettävä todella luottamuksellisia tietoja tokenissa, on käytettävä JWE-muotoa (JSON Web Encryption), joka lisää salauskerroksen allekirjoituksen päälle. Käytännössä JWE on harvinainen : on suositeltavampaa olla laittamatta arkaluonteisia tietoja tokeniin ja säilyttää kriittiset tiedot palvelimen tietokannassa.
Miten JWT peruutetaan ennen sen vanhenemista?
Tämä on yksi JWT:n heikkouksista : rakenteensa vuoksi palvelimen ei tarvitse tallentaa tokenin
tilaa, joten se ei myöskään tiedä, miten se merkitään peruutetuksi. On olemassa kolme
lähestymistapaa. Peruutusluettelo (Revocation list) : pidetään palvelinpuolella
luetteloa mitätöidyistä jti-tunnisteista ja tarkistetaan se jokaisen pyynnön
yhteydessä. Lyhyet elinkaaret : myönnetään 5–15 minuuttia voimassa olevia
pääsytokeneita ja käytetään palvelinpuolella peruutettavissa olevaa päivitystokenia uusien
generoimiseen. Allekirjoitusavaimen kierto (Rotation) : mitätöidään koko
token-sukupolvi vaihtamalla avain. Toinen lähestymistapa on ylivoimaisesti yleisin.
Mitä eroa on JWT-tokenilla ja perinteisellä istunnolla?
Perinteinen istunto tallentaa läpinäkymättömän tunnisteen asiakaspuolelle (yleensä evästeeseen) ja säilyttää kaikki siihen liittyvät tiedot (käyttäjä, oikeudet, vanheneminen) palvelimen muistissa tai tietokannassa. JWT sen sijaan kuljettaa nämä tiedot suoraan allekirjoitetussa tokenissa. JWT:n etu : palvelimen ei tarvitse tallentaa istuntoa, mikä helpottaa horisontaalista skaalausta ja mikropalveluarkkitehtuuria. Haitat : peruuttaminen on monimutkaisempaa, token on suurempi jokaisessa pyynnössä ja mikä tahansa vuoto paljastaa hyötykuorman.
Mitä eroa on JWT-, JWS- ja JWE-termeillä?
JWT (RFC 7519) on yleinen token-muoto. Se voidaan toteuttaa kahdella tavalla : JWS (RFC 7515, JSON Web Signature), joka vain allekirjoittaa hyötykuorman, ja JWE (RFC 7516, JSON Web Encryption), joka salaa sen. Käytännössä kun puhutaan "JWT-tokenista" ilman tarkennusta, tarkoitetaan lähes aina JWS-tokenia : allekirjoitettua, mutta kaikkien luettavissa olevaa tokenia. JWE-muotoa käytetään tilanteissa, joissa hyötykuorman luottamuksellisuus on välttämätöntä, esimerkiksi tietyissä edistyneissä OpenID Connect -skenaarioissa.
Miksi API ei hyväksy JWT-tokeniani?
Yleisimmät syyt tärkeysjärjestyksessä : token on vanhentunut (tarkista
exp-väittämä), allekirjoitus on virheellinen (salainen tai
julkinen avain ei vastaa lähettäjän käyttämää), väärä aud
(token on myönnetty toiselle palvelulle), väärä iss
(ilmoitettu lähettäjä ei ole odotettu), hylätty algoritmi (API vaatii
esimerkiksi RS256:ta, mutta saa HS256:n), kellojen epäsynkroni lähettäjän ja
tarkistajan välillä (vaikuttaa exp- ja nbf-arvoihin). Tokenin dekoodaus
tällä työkalulla auttaa sulkemaan pois puolet mahdollisista syistä lukemalla väittämät suoraan.
Miten generoida JWT?
Useimmille kielille on olemassa omat kirjastonsa : jsonwebtoken (Node.js),
PyJWT (Python), lcobucci/jwt tai firebase/php-jwt (PHP),
jjwt (Java), golang-jwt/jwt (Go). Kaikki ne ottavat syötteenä
hyötykuorma-objektin, avaimen ja algoritmin, ja palauttavat merkkijonon
header.payload.signature valmiina lähetettäväksi. On erittäin epäsuositeltavaa
toteuttaa generointi itse : kryptografiaan liittyy liikaa sudenkuoppia (ei-vakiot vertailut,
alg: none -käsittelyvirheet jne.).
Hyväksyykö dekooderi vanhentuneen JWT-tokenin?
Kyllä. Dekooderi vain näyttää tokenin sisällön ottamatta kantaa sen ajalliseen voimassaoloon. Se
ei arvioi exp- tai nbf-arvoja eikä allekirjoitusta. Tämä on hyödyllistä
ymmärtääksesi, miksi API hylkäsi tokenin : voit verrata exp-arvoa nykyhetkeen
varmistaaksesi, onko se todella vanhentunut.
Onko JWT-tokenini pätevä, jos dekooderi näyttää sen oikein?
Ei. Näyttäminen todistaa vain, että merkkijono on oikeassa muodossa (kolme pisteillä erotettua osaa, oikea Base64URL-koodaus, kelvollinen JSON otsikossa ja hyötykuormassa). Se ei kerro mitään tokenin aitoudesta. Täysin väärennetty JWT voi näkyä virheettömästi dekooderissa, ja juuri siksi se on tarkistettava vahvistajalla.
Pyyntöesimerkki
curl -X POST https://cdrn.fr/api/v1/tools/jwt-decoder/execute \
-H "Content-Type: application/json" \
-d '{"token":"..."}'
Syöteskeema
| Kenttä | Tyyppi | Pakollinen | Oletus |
|---|---|---|---|
token |
text | ✓ | – |
Päätepisteet
GET https://cdrn.fr/api/v1/tools- listaa kaikki saatavilla olevat työkalutGET https://cdrn.fr/api/v1/tools/jwt-decoder- hakee tämän työkalun skeemanPOST https://cdrn.fr/api/v1/tools/jwt-decoder/execute- suorittaa tämän työkalun JSON-payloadilla