JWT Internals în .NET
Doru Bulubasa
02 March 2026

Ce se întâmplă de fapt într-un JSON Web Token

JWT este probabil cel mai folosit mecanism de autentificare în aplicațiile moderne:

  • ASP.NET Core Web API

  • Blazor WebAssembly

  • Microservices

  • Mobile apps

  • SPA + API

Dar foarte puțini înțeleg ce se întâmplă matematic și criptografic în spate.

JWT nu este „doar un string”. Este un mecanism de semnare criptografică.


🧩 1️⃣ Structura JWT – Header / Payload / Signature

Un JWT arată așa:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiQWRtaW4iLCJleHAiOjE3MTk5OTk5OTl9
.
Zx3Kp4...

Are 3 părți:

Base64Url(Header) .
Base64Url(Payload) .
Signature


🔹 Header

Conține:

{
  "alg": "RS256",
  "typ": "JWT"
}

  • alg = algoritmul de semnare

  • typ = tipul token-ului

Aici alegi HMAC, RSA sau ECDSA.


🔹 Payload

Conține claims:

{
  "sub": "123456",
  "email": "user@email.com",
  "role": "Admin",
  "exp": 1719999999
}

⚠ Important:

Payload-ul NU este criptat. Este doar Base64Url encoded.

Oricine poate decoda conținutul. JWT protejează integritatea, nu confidențialitatea.


🔹 Signature

Se calculează astfel:

Signature = Sign(
    Base64Url(Header) + "." + Base64Url(Payload),
    SecretOrPrivateKey
)

Dacă cineva modifică payload-ul:

→ semnătura devine invalidă

→ token-ul este respins


🔐 2️⃣ HMAC vs RSA vs ECDSA

Aici apar diferențele serioase.


🔸 HS256 (HMAC – cheie simetrică)

  • aceeași cheie pentru semnare și validare

  • simplu

  • rapid

  • periculos în microservices

Dacă cheia este compromisă:

→ oricine poate genera token-uri valide

Bun pentru:

  • aplicații monolit

  • sisteme interne


🔸 RS256 (RSA – cheie asimetrică)

  • Private Key → semnează

  • Public Key → validează

Avantaj major:

  • API-ul poate valida fără să dețină cheia privată

Perfect pentru:

  • microservices

  • identity server separat

  • scenarii enterprise

Recomandat în 2026.


🔸 ES256 (ECDSA)

  • mai rapid

  • chei mai mici

  • performanță mai bună

Tot asimetric.

Folosit din ce în ce mai mult în sisteme moderne.


🧠 3️⃣ Cum verifică ASP.NET Core semnătura

În Program.cs:

builder.Services
    .AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "https://your-auth-server",
            ValidAudience = "your-api",
            IssuerSigningKey = new RsaSecurityKey(publicKey)
        };
    });

Ce face framework-ul intern:

  1. Parsează header

  2. Citește algoritmul

  3. Reconstruiește Header.Payload

  4. Verifică semnătura cu cheia

  5. Verifică expirarea

  6. Creează ClaimsPrincipal

Dacă semnătura e invalidă → 401 automat.


🚨 4️⃣ Ce NU trebuie pus niciodată în JWT

Greșeală extrem de frecventă.

Nu pune în JWT:

❌ Parole

❌ Hash-uri

❌ Chei API

❌ Date sensibile (CNP, IBAN)

❌ Permisiuni dinamice complexe

❌ CompanyId fără verificare suplimentară

JWT este trimis la fiecare request.

Dacă e furat → atacatorul îl poate folosi până expiră.


⚠ 5️⃣ De ce JWT NU înseamnă automat securitate

Multe aplicații cred:

„Avem JWT, suntem securizați.”

Fals.

Probleme reale:

  • Token fără expirare

  • Cheie hardcodată în cod

  • Fără validare issuer

  • Fără validare audience

  • Acceptă orice algoritm

  • Nu există revocare

  • Nu există refresh token rotation

JWT rezolvă:

→ autentificarea stateless

Nu rezolvă:

→ authorization corectă

→ revocarea token-ului

→ protecția împotriva XSS

→ protecția împotriva CSRF

→ rate limiting


🔥 Atacuri frecvente pe JWT

1️⃣ Alg = none attack

Dacă aplicația nu validează algoritmul → atacatorul elimină semnătura.

2️⃣ Key confusion attack

Confuzie între HMAC și RSA.

3️⃣ Stolen token reuse

JWT furat prin XSS → folosit până expiră.

4️⃣ Long expiration

Token valabil 24h+ → risc mare.


🧱 Best Practices JWT în .NET (2026)

✔ Folosește RSA sau ECDSA

✔ Chei stocate în Key Vault

✔ Expirare scurtă (5–15 minute)

✔ Refresh token rotation

✔ Validare issuer & audience

✔ ValidateLifetime activ

✔ Nu dezactiva verificarea semnăturii niciodată

✔ Logging la token invalid


🎯 Exemplu arhitectură corectă

Client (Blazor / SPA)

→ primește Access Token (10 min)

→ primește Refresh Token (HttpOnly cookie)

API:

→ validează semnătura

→ validează claims

→ validează authorization policy

Identity server:

→ semnează cu private key

→ rotește refresh tokens

→ suport revocare


🏁 Concluzie

JWT este:

✔ elegant

✔ scalabil

✔ performant

Dar este securizat doar dacă:

este implementat corect.