S-ar putea ca criptarea unui JWT semnat să fie viabilă pentru a securiza încărcătura utilă a cererilor? (Securitatea informațiilor, Criptare, Autentificare, Token, Jwt)

scniro a intrebat.

Lucrez la o aplicație web server-client și, ca o schemă de autentificare, emit baza64 codificată json web token-uri. Luați în considerare următorul token…

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Decodat ca atare…

{
  "alg": "HS256",        // header
  "typ": "JWT"
},
{
  "sub": "1234567890",   // payload
  "name": "John Doe",
  "admin": true
},
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), 'secret') // signature 

Preocuparea mea este legată de payload porțiunea din acest token, unde doresc să furnizez declarații definite, de ex. "role": "readonly". Preocuparea mea este ca aceste valori să fie vizibile și să fie modificate de către utilizatorul final odată ce au fost emise. Modificarea acestei părți va nu invalida verificarea semnăturii. Nu doresc să păstrez date pe server pentru a reverifica/compara jetoanele emise – doresc să păstrez serverul. complet fără stare.

M-am gândit să semnez jetonul, să îl criptez prin AES 256 și să îl folosesc ca „jeton”. Fluxul ar fi rezumat astfel…

  1. generarea și semnarea unui token codificat în baza64
  2. criptarea token-ului pe server prin AES 256
  3. Emiterea jetonului criptat către client


  4. cerere primită, token criptat furnizat

  5. decriptarea jetonului pe partea serverului
  6. validarea codării base64 original semnătura jetonului (acum se poate asigura că cererile nu au fost modificate)

Părerea mea este că afirmațiile (încărcătura utilă) nu vor fi văzute, iar orice manipulare a acestei valori criptate nu va fi, evident, decriptată așa cum se așteaptă partea serverului. Întrebarea mea este. este acest lucru viabil? Nu am putut găsi prea multe pe web pentru criptarea unor token-uri întregi. Există o modalitate mai bună?

Comentarii

  • De ce nu ar trebui să se facă afirmații precum role să fie incluse în semnătură? Cred că întregul conținut al JWT este semnat. –  > Por Neil Smithline.
  • @NeilSmithline mulțumim pentru comentariul pe această temă. Și eu m-aș fi așteptat la asta, dar dacă validez un token semnat inițial prin modificarea conținutului, tot obțin o verificare validă. Poate că node-jsonwebtoken nu funcționează așa cum mă aștept, sau îmi scapă ceva cu totul. Sper că aveți dreptate, sincer, și că îmi scapă ceva…  > Por scniro.
  • abstract al specificației afirmă că revendicările sunt digitally signed or integrity protected. Nu sunt sigur care ar trebui să fie următorul pas. Poate că ați putea include în întrebarea dvs. o mostră a simbolului pe care îl modificați? –  > Por Neil Smithline.
  • @NeilSmithline ah ai dreptate, am folosit jwt.io pentru a modifica conținutul, dar nu am văzut că într-adevăr modifică și semnătura. Ar mai fi utilă criptarea jetonului dacă aș vrea să păstrez informații sensibile în jeton? –  > Por scniro.
  • Sigur, cred că JWT acceptă criptarea în mod nativ (a se vedea exemplul). Folosirea acestuia va fi probabil mai bună decât orice soluție proprie pe care o veți găsi. Acestea fiind spuse, acest lucru iese un pic din zona mea de confort. –  > Por Neil Smithline.
1 răspunsuri
canal

Cred că puneți două întrebări:

  1. schimbarea încărcăturii utile invalidează semnătura: TL;DR: da
  2. adăugarea criptării peste JWT vă oferă autenticitatea conținutului: TL;DR: nu vă criptați, folosiți JWE!

Iată răspunsurile mai în detaliu:

(1) Conform specificațiilor, https://www.rfc-editor.org/rfc/rfc7515.txt

semnătura unui JWT semnat (JWS) este calculată pe antetul protejat, precum și pe încărcătura utilă:

(a se vedea secțiunea 5.1. Semnătura mesajului sau calculul MAC)

Compute the JWS Signature in the manner defined for the
       particular algorithm being used over the JWS Signing Input
       ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' ||
       BASE64URL(JWS Payload)). 

Prin urmare, modificarea încărcăturii utile ar trebui să invalideze semnătura.

(2) NU vă criptați propriul JWT!!! Există o specificație reală care definește modul de criptare a JWT-urilor (numită JWE):https://www.rfc-editor.org/rfc/rfc7516.txt

JWE utilizează criptarea autentificată, ceea ce înseamnă că textul în clar este mai întâi criptat și apoi se produce o verificare a integrității asupra textului cifrat. puteți obține mai multe informații despre cum arată textul în clar din secțiunea 5.1 a specificației de mai sus.

Este posibil să stocați în siguranță politicile de acces în încărcătura utilă a JWT-ului dumneavoastră dacă utilizați formate criptate sau semnate. Este posibil să doriți să folosiți un format criptat dacă nu doriți ca clientul sau alte părți să aibă cunoștință de datele politicii. Dacă nu vă interesează cine le poate citi și vă interesează doar cine poate modifica valorile, utilizați doar semnăturile.

Nu uitați însă că, cu cât adăugați mai multă securitate, cu atât mai mare este impactul asupra performanței, așa că trebuie să judecați în funcție de ceea ce este necesar.

Notă finală: Gestionarea cheilor de semnătură și de criptare devine, de asemenea, un aspect important pe care trebuie să îl luați în considerare, deoarece, la sfârșitul zilei, oricine are acces la chei poate decripta JWE sau modifica semnătura JWS. Așadar, asigurați-vă că utilizați bune practici de siguranță în ceea ce privește locul în care stocați cheile efective, cine are acces la acestea și modul în care acestea sunt utilizate și păstrate în memorie.

Comentarii

  • Vă mulțumim pentru răspuns! Deși cu întârziere, acum sunt de acord cu fiecare punct pe care l-ați menționat de când am pus această întrebare. În cazul meu, asigurarea că semnătura va fi invalidată în cazul în care jetonul este falsificat este suficientă pentru mine. Nu mai am nevoie să stochez informații sensibile în token, dar da, aș folosi un JWE dacă aș mai avea nevoie de acest lucru! –  > Por scniro.