RO EN

JWT Internals in .NET

JWT Internals in .NET
Doru Bulubasa
02 March 2026

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:

  1. Parses the header

  2. Reads the algorithm

  3. Reconstructs Header.Payload

  4. Verifies the signature with the key

  5. Checks expiration

  6. 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.