JOSE/JWT Asimmetrico in DelphiMVCFramework: RS256, ECDSA, EdDSA e OpenSSL Moderno

JOSE, JWT e gli Standard di Settore
Per chi non mastica crittografia quotidianamente, vale la pena inquadrare il contesto. JOSE (Javascript Object Signing and Encryption) è la famiglia di standard IETF che definisce come firmare e cifrare dati in formato JSON. Include:
- JWT (RFC 7519) — il formato del token (header, payload, firma)
- JWS (RFC 7515) — la firma digitale dei token
- JWA (RFC 7518) — gli algoritmi crittografici supportati
- JWK (RFC 7517) — la rappresentazione delle chiavi in formato JSON
Fino a oggi, DelphiMVCFramework supportava JWT con gli algoritmi HMAC simmetrici (HS256/384/512) — la scelta più comune e perfettamente adeguata per la maggior parte delle applicazioni. Tuttavia, quando l’architettura cresce verso i microservizi, il modello simmetrico impone un compromesso: o tutti i server conoscono lo stesso segreto (aumentando la superficie di attacco), oppure ogni servizio deve validare i token contattando un unico server di autenticazione centralizzato (creando un collo di bottiglia e un single point of failure). La firma asimmetrica elimina entrambi i problemi.
Firma Asimmetrica JWT in Delphi: il Pezzo Mancante
Con la firma asimmetrica il paradigma cambia: l’auth server firma con una chiave privata che non lascia mai quella macchina, e tutti gli altri servizi verificano con la chiave pubblica, che può essere distribuita liberamente. Questo è lo standard per OpenID Connect, OAuth 2.0, e qualsiasi architettura moderna a microservizi.
DelphiMVCFramework ora implementa la copertura completa degli algoritmi JWA per JWS:
| Famiglia | Algoritmi | Note |
|---|---|---|
| HMAC | HS256, HS384, HS512 | Segreto condiviso (già supportato) |
| RSA PKCS#1 | RS256, RS384, RS512 | Compatibilità massima, OIDC |
| RSA-PSS | PS256, PS384, PS512 | Più sicuro di RS*, stesse chiavi RSA |
| ECDSA | ES256, ES384, ES512 | Chiavi molto più piccole di RSA |
| EdDSA | Ed25519 | Il più veloce, chiavi da 32 byte |
Sedici algoritmi. Quattro famiglie crittografiche. Tutti accessibili attraverso la stessa interfaccia IJWTSigner, che si integra con il middleware JWT esistente senza cambiare una riga di codice nella logica applicativa.
Questo significa che un’applicazione DelphiMVCFramework può ora interoperare nativamente con identity provider come Auth0, Keycloak, Azure AD e Google Identity, che emettono token RS256 o ES256.
OpenSSL 3.x via TaurusTLS
Una scelta architetturale precisa: i nuovi signer non usano le librerie OpenSSL 1.0.x distribuite con Indy (End of Life dalla fine del 2019). Usano TaurusTLS per accedere a OpenSSL 1.1.1+ e 3.x — algoritmi moderni, patch di sicurezza attive, performance superiori.
Dipendenza Opzionale: Zero Impatto sul Codice Esistente
Chi usa HS256 non deve cambiare nulla. TaurusTLS serve solo se usi algoritmi asimmetrici.
L’interfaccia IJWTSigner è definita nel core del framework senza dipendenze esterne. Le implementazioni RSA/ECDSA/EdDSA vivono in una unit separata (MVCFramework.JWT.RSA) che includi solo quando ne hai bisogno.
Come Passare da HS256 a RS256 in DelphiMVCFramework
// PRIMA: HMAC (segreto condiviso)
Engine.AddMiddleware(UseJWTMiddleware(AuthHandler, ClaimsSetup,
'my_shared_secret', '/login', [...], 300));
// DOPO: RSA (chiave asimmetrica)
uses MVCFramework.JWT.RSA;
var lSigner := TRSAJWTSigner.CreateFromFiles(JWT_RS256,
'keys/private.pem', 'keys/public.pem');
Engine.AddMiddleware(UseJWTMiddleware(AuthHandler, ClaimsSetup,
lSigner, '/login', [...], 300));
Una unit in più nella uses, una riga per creare il signer, un parametro diverso nel middleware. Controller, auth handler, claims: tutto identico.
E se un microservizio deve solo verificare token senza firmarli:
var lSigner := TRSAJWTSigner.CreateVerifyOnly(JWT_RS256,
TFile.ReadAllText('public.pem'));
La chiave privata non esiste nemmeno su quella macchina.
Esempio Completo: Creare e Verificare un Token RS256
uses
MVCFramework.JWT,
MVCFramework.JWT.RSA; // richiede TaurusTLS + OpenSSL 1.1.1+
// --- 1. CREARE UN TOKEN (auth server) ---
var lSigner := TRSAJWTSigner.CreateFromFiles(
JWT_RS256, 'keys/private.pem', 'keys/public.pem');
var lJWT := TJWT.Create(lSigner);
try
lJWT.Claims.Issuer := 'my-auth-server';
lJWT.Claims.Subject := 'user42';
lJWT.Claims.ExpirationTime := Now + OneHour;
lJWT.Claims.IssuedAt := Now;
lJWT.CustomClaims['role'] := 'admin';
var lToken := lJWT.GetToken;
// eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOi...
finally
lJWT.Free;
end;
// --- 2. VERIFICARE IL TOKEN (microservizio, solo chiave pubblica) ---
var lVerifier := TRSAJWTSigner.CreateVerifyOnly(
JWT_RS256, TFile.ReadAllText('keys/public.pem'));
var lVerifyJWT := TJWT.Create(lVerifier);
try
var lError: string;
if lVerifyJWT.LoadToken(lToken, lError) then
begin
WriteLn('Issuer: ', lVerifyJWT.Claims.Issuer); // my-auth-server
WriteLn('Subject: ', lVerifyJWT.Claims.Subject); // user42
WriteLn('Role: ', lVerifyJWT.CustomClaims['role']); // admin
end;
finally
lVerifyJWT.Free;
end;
Tutta la Complessità è nel Middleware
In DelphiMVCFramework non devi scrivere codice come quello sopra per ogni richiesta. Il middleware JWT gestisce automaticamente l’intero ciclo: intercetta le richieste, estrae il token dall’header Authorization: Bearer, lo verifica con il signer configurato, popola Context.LoggedUser con claims e ruoli, e rifiuta le richieste non valide con il codice HTTP appropriato. Il tuo controller riceve la richiesta solo se il token è valido — e a quel punto ha già a disposizione l’utente autenticato e i suoi ruoli, senza una sola riga di codice JWT.
Sicurezza JWT Integrata
Oltre agli algoritmi, l’implementazione include protezioni concrete:
- Algorithm Confusion Prevention: il token non può dichiarare un algoritmo diverso da quello configurato nel signer — previene il noto attacco dove un token RS256 viene ri-firmato come HS256 usando la chiave pubblica
- Constant-Time Comparison: la verifica HMAC usa confronto a tempo costante per prevenire timing attacks
- Sign-Only / Verify-Only: un microservizio che deve solo verificare token può essere configurato con la sola chiave pubblica — la chiave privata non viene mai deployata su quella macchina, eliminando il rischio che venga compromessa
Quality: Nessuna Funzionalità Senza Unit Test
Come ogni funzionalità di DelphiMVCFramework, anche il supporto JOSE/JWS è coperto da una nutrita batteria di unit test. Nessuna funzionalità viene rilasciata senza test automatizzati che ne verifichino il corretto funzionamento su tutte le piattaforme supportate. I test coprono tutti e 16 gli algoritmi su Win32 e Win64, inclusi scenari di tamper detection, chiavi errate, algorithm mismatch e backward compatibility con il codice esistente.
E Dopo? JWE e JWK
Il supporto JWS completo è il primo passo. L’architettura basata su IJWTSigner apre la strada a JWE (JSON Web Encryption, RFC 7516) per token cifrati e a JWK (RFC 7517) per la gestione delle chiavi in formato JSON — inclusi gli endpoint JWKS per la distribuzione automatica delle chiavi pubbliche. Stay tuned.
A ITDevCon 2026 Spring Edition
Questa è solo una delle novità che presenterò a ITDevCon 2026 Spring Edition. Vedremo demo live di architetture a microservizi con firma asimmetrica, integrazione con identity provider moderni, e molto altro.
Tutto quello che avete letto in questo articolo è già implementato e funzionante nella versione 3.5.0-silicon attualmente in beta su GitHub. La release stabile è prevista prima di ITDevCon 2026 Spring Edition.
Comments
comments powered by Disqus