What actually happens inside a JSON Web Token
JWT is probably the most used authentication mechanism in modern applications:
-
ASP.NET Core Web API
-
Blazor WebAssembly
-
Microservices
-
Mobile apps
-
SPA + API
But very few understand what happens mathematically and cryptographically behind the scenes.
JWT is not "just a string". It is a cryptographic signing mechanism.
🧩 1️⃣ JWT Structure – Header / Payload / Signature
A JWT looks like this:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTYiLCJyb2xlIjoiQWRtaW4iLCJleHAiOjE3MTk5OTk5OTl9
.
Zx3Kp4...
It has 3 parts:
Base64Url(Header) .
Base64Url(Payload) .
Signature
🔹 Header
Contains:
{
"alg": "RS256",
"typ": "JWT"
}
-
alg = signing algorithm
-
typ = token type
Here you choose HMAC, RSA, or ECDSA.
🔹 Payload
Contains claims:
{
"sub": "123456",
"email": "user@email.com",
"role": "Admin",
"exp": 1719999999
}
⚠ Important:
The payload is NOT encrypted. It is only Base64Url encoded.
Anyone can decode the content. JWT protects integrity, not confidentiality.
🔹 Signature
Calculated as follows:
Signature = Sign(
Base64Url(Header) + "." + Base64Url(Payload),
SecretOrPrivateKey
)
If someone modifies the payload:
→ the signature becomes invalid
→ the token is rejected
🔐 2️⃣ HMAC vs RSA vs ECDSA
Here the serious differences appear.
🔸 HS256 (HMAC – symmetric key)
-
same key for signing and validation
-
simple
-
fast
-
dangerous in microservices
If the key is compromised:
→ anyone can generate valid tokens
Good for:
-
monolithic applications
-
internal systems
🔸 RS256 (RSA – asymmetric key)
-
Private Key → signs
-
Public Key → validates
Major advantage:
-
The API can validate without holding the private key
Perfect for:
-
microservices
-
separate identity server
-
enterprise scenarios
Recommended in 2026.
🔸 ES256 (ECDSA)
-
faster
-
smaller keys
-
better performance
Still asymmetric.
Increasingly used in modern systems.
🧠 3️⃣ How ASP.NET Core verifies the signature
In 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)
};
});
What the internal framework does:
-
Parses the header
-
Reads the algorithm
-
Reconstructs Header.Payload
-
Verifies the signature with the key
-
Checks expiration
-
Creates ClaimsPrincipal
If the signature is invalid → 401 automatically.
🚨 4️⃣ What should NEVER be put in a JWT
Extremely common mistake.
Do not put in JWT:
❌ Passwords
❌ Hashes
❌ API keys
❌ Sensitive data (Personal ID number, IBAN)
❌ Complex dynamic permissions
❌ CompanyId without additional verification
JWT is sent with every request.
If stolen → attacker can use it until it expires.
⚠ 5️⃣ Why JWT does NOT automatically mean security
Many applications believe:
"We have JWT, we are secure."
False.
Real problems:
-
Token without expiration
-
Hardcoded key in code
-
No issuer validation
-
No audience validation
-
Accepts any algorithm
-
No revocation
-
No refresh token rotation
JWT solves:
→ stateless authentication
Does not solve:
→ correct authorization
→ token revocation
→ protection against XSS
→ protection against CSRF
→ rate limiting
🔥 Common JWT attacks
1️⃣ Alg = none attack
If the application does not validate the algorithm → attacker removes the signature.
2️⃣ Key confusion attack
Confusion between HMAC and RSA.
3️⃣ Stolen token reuse
JWT stolen via XSS → used until it expires.
4️⃣ Long expiration
Token valid 24h+ → high risk.
🧱 Best Practices JWT in .NET (2026)
✔ Use RSA or ECDSA
✔ Keys stored in Key Vault
✔ Short expiration (5–15 minutes)
✔ Refresh token rotation
✔ Validate issuer & audience
✔ ValidateLifetime active
✔ Never disable signature verification
✔ Logging on invalid token
🎯 Correct architecture example
Client (Blazor / SPA)
→ receives Access Token (10 min)
→ receives Refresh Token (HttpOnly cookie)
API:
→ validates signature
→ validates claims
→ validates authorization policy
Identity server:
→ signs with private key
→ rotates refresh tokens
→ supports revocation
🏁 Conclusion
JWT is:
✔ elegant
✔ scalable
✔ performant
But it is secure only if:
it is implemented correctly.