Become a member!

JOSE/JWT Asimétrico en DelphiMVCFramework: RS256, ECDSA, EdDSA y OpenSSL Moderno

🌐
Este artículo también está disponible en otros idiomas:
🇬🇧 English  •  🇮🇹 Italiano

Candado de combinación de latón sobre un teclado blanco junto a tarjetas con chip, símbolo de la seguridad de los tokens

JOSE, JWT y los Estándares de la Industria

JOSE (Javascript Object Signing and Encryption) es la familia de estándares IETF que define cómo firmar y cifrar datos en formato JSON. Incluye:

  • JWT (RFC 7519) — el formato del token (header, payload, firma)
  • JWS (RFC 7515) — la firma digital de los tokens
  • JWA (RFC 7518) — los algoritmos criptográficos soportados
  • JWK (RFC 7517) — la representación de claves en formato JSON

Hasta ahora, DelphiMVCFramework soportaba JWT con algoritmos HMAC simétricos (HS256/384/512) — la opción más común, perfectamente adecuada para la mayoría de las aplicaciones. Sin embargo, cuando la arquitectura crece hacia los microservicios, el modelo simétrico impone un compromiso: o todos los servidores conocen el mismo secreto (aumentando la superficie de ataque), o cada servicio debe validar los tokens contactando un único servidor de autenticación centralizado (creando un cuello de botella y un single point of failure). La firma asimétrica elimina ambos problemas.

Firma Asimétrica JWT en Delphi: la Pieza que Faltaba

Con la firma asimétrica, el paradigma cambia: el servidor de autenticación firma con una clave privada que nunca sale de esa máquina, y todos los demás servicios verifican con la clave pública, que puede distribuirse libremente. Este es el estándar para OpenID Connect, OAuth 2.0, y cualquier arquitectura moderna de microservicios.

DelphiMVCFramework ahora implementa la cobertura completa de los algoritmos JWA para JWS:

FamiliaAlgoritmosNotas
HMACHS256, HS384, HS512Secreto compartido (ya soportado)
RSA PKCS#1RS256, RS384, RS512Máxima compatibilidad, OIDC
RSA-PSSPS256, PS384, PS512Más seguro que RS*, mismas claves RSA
ECDSAES256, ES384, ES512Claves mucho más pequeñas que RSA
EdDSAEd25519El más rápido, claves de 32 bytes

Dieciséis algoritmos. Cuatro familias criptográficas. Todos accesibles a través de la misma interfaz IJWTSigner, que se integra con el middleware JWT existente sin cambiar una sola línea en la lógica de la aplicación.

Esto significa que una aplicación DMVCFramework puede ahora interoperar nativamente con proveedores de identidad como Auth0, Keycloak, Azure AD y Google Identity, que emiten tokens RS256 o ES256.

OpenSSL 3.x vía TaurusTLS

Una decisión arquitectónica deliberada: los nuevos signers no usan las librerías OpenSSL 1.0.x distribuidas con Indy (End of Life desde finales de 2019). Usan TaurusTLS para acceder a OpenSSL 1.1.1+ y 3.x — algoritmos modernos, parches de seguridad activos, rendimiento superior.

Dependencia Opcional: Cero Impacto en el Código Existente

Si usas HS256, no necesitas cambiar nada. TaurusTLS se requiere solo cuando usas algoritmos asimétricos.

La interfaz IJWTSigner está definida en el core del framework sin dependencias externas. Las implementaciones RSA/ECDSA/EdDSA viven en una unit separada (MVCFramework.JWT.RSA) que incluyes solo cuando la necesitas.

Cómo Pasar de HS256 a RS256 en DelphiMVCFramework

// ANTES: HMAC (secreto compartido)
Engine.AddMiddleware(UseJWTMiddleware(AuthHandler, ClaimsSetup,
  'my_shared_secret', '/login', [...], 300));

// DESPUÉS: RSA (par de claves asimétricas)
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 más en la cláusula uses, una línea para crear el signer, un parámetro diferente en el middleware. Controladores, auth handler, claims: todo idéntico.

Y si un microservicio solo necesita verificar tokens sin firmarlos:

var lSigner := TRSAJWTSigner.CreateVerifyOnly(JWT_RS256,
  TFile.ReadAllText('public.pem'));

La clave privada ni siquiera existe en esa máquina.

Ejemplo Completo: Crear y Verificar un Token RS256

uses
  MVCFramework.JWT,
  MVCFramework.JWT.RSA;  // requiere TaurusTLS + OpenSSL 1.1.1+

// --- 1. CREAR UN TOKEN (servidor de autenticación) ---

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. VERIFICAR EL TOKEN (microservicio, solo clave pública) ---

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;

Toda la Complejidad Está en el Middleware

En DelphiMVCFramework no necesitas escribir código como el anterior para cada petición. El middleware JWT gestiona automáticamente el ciclo completo: intercepta las peticiones, extrae el token del header Authorization: Bearer, lo verifica con el signer configurado, rellena Context.LoggedUser con claims y roles, y rechaza las peticiones no válidas con el código HTTP apropiado. Tu controller recibe la petición solo si el token es válido — y en ese punto el usuario autenticado y sus roles ya están disponibles, sin una sola línea de código JWT.

Seguridad JWT Integrada

Más allá de los algoritmos, la implementación incluye protecciones concretas:

  • Algorithm Confusion Prevention: el token no puede declarar un algoritmo diferente al configurado en el signer — previene el conocido ataque donde un token RS256 se re-firma como HS256 usando la clave pública
  • Constant-Time Comparison: la verificación HMAC usa comparación a tiempo constante para prevenir timing attacks
  • Sign-Only / Verify-Only: un microservicio que solo necesita verificar tokens puede configurarse con la sola clave pública — la clave privada nunca se despliega en esa máquina, eliminando el riesgo de que sea comprometida

Calidad: Ninguna Funcionalidad se Publica sin Unit Tests

Como cada funcionalidad de DelphiMVCFramework, el soporte JOSE/JWS está respaldado por una amplia batería de tests automatizados. Ninguna funcionalidad se publica jamás sin tests que verifiquen su correcto funcionamiento en todas las plataformas soportadas. Los tests cubren los 16 algoritmos en Win32 y Win64, incluyendo detección de manipulación, claves incorrectas, algorithm mismatch y backward compatibility con el código existente.

¿Y Después? JWE y JWK

El soporte completo de JWS es el primer paso. La arquitectura basada en IJWTSigner abre el camino hacia JWE (JSON Web Encryption, RFC 7516) para tokens cifrados y JWK (RFC 7517) para la gestión de claves en formato JSON — incluyendo endpoints JWKS para la distribución automática de claves públicas. Stay tuned.

Preguntas frecuentes

¿Qué algoritmos JWT soporta DelphiMVCFramework?

Dieciséis: HS256, HS384, HS512 (HMAC simétrico), RS256, RS384, RS512 (RSA PKCS#1), PS256, PS384, PS512 (RSA-PSS), ES256, ES384, ES512 (ECDSA) y EdDSA con Ed25519.

¿Cómo se usa RS256 con DelphiMVCFramework?

Se agrega MVCFramework.JWT.RSA a la cláusula uses, se crea un TRSAJWTSigner con los archivos PEM de las claves RSA y se pasa a UseJWTMiddleware en lugar de la cadena secreta. El resto del código (controladores, auth handler, claims) permanece idéntico.

¿DelphiMVCFramework requiere TaurusTLS para JWT?

No. TaurusTLS solo se requiere para los algoritmos asimétricos (RS256, PS256, ES256, EdDSA). Si se usan los algoritmos HMAC simétricos (HS256, HS384, HS512), no se necesita ninguna dependencia adicional.

¿DelphiMVCFramework es compatible con Auth0, Keycloak y Azure AD?

Sí. Con soporte para RS256 y ES256, DelphiMVCFramework puede verificar nativamente tokens JWT emitidos por Auth0, Keycloak, Azure AD, Google Identity y cualquier proveedor de identidad compatible con OpenID Connect.

En ITDevCon 2026 Spring Edition

Esta es solo una de las novedades que presentaré en ITDevCon 2026 Spring Edition. Veremos demos en vivo de arquitecturas de microservicios con firma asimétrica, integración con proveedores de identidad modernos, y mucho más.

Todo lo descrito en este artículo ya está implementado y funcionando en la versión 3.5.0-silicon, actualmente en beta en GitHub. La release estable está prevista antes de ITDevCon 2026 Spring Edition.

Datos clave

DelphiMVCFramework añade la firma JWS asimétrica a su soporte JWT, siguiendo los estándares JOSE.

  • Estándares implicados: JWT (RFC 7519), JWS (RFC 7515), JWA (RFC 7518), JWK (RFC 7517)
  • 16 algoritmos en cuatro familias: HMAC HS256/384/512, RSA PKCS#1 RS256/384/512, RSA-PSS PS256/384/512, ECDSA ES256/384/512, EdDSA con Ed25519
  • Todos los signers implementan la interfaz IJWTSigner y se conectan al middleware JWT existente (UseJWTMiddleware)
  • Los signers asimétricos están en la unit MVCFramework.JWT.RSA y usan TaurusTLS con OpenSSL 1.1.1+ y 3.x, no las librerías OpenSSL 1.0.x de Indy
  • TaurusTLS es una dependencia opcional: quien usa HS256/384/512 no cambia nada
  • TRSAJWTSigner.CreateFromFiles carga pares de claves PEM; TRSAJWTSigner.CreateVerifyOnly permite a un microservicio verificar tokens solo con la clave pública
  • Protecciones incluidas: prevención de algorithm confusion, comparación HMAC en tiempo constante, configuraciones sign-only y verify-only
  • Interopera con tokens RS256/ES256 de Auth0, Keycloak, Azure AD, Google Identity y otros proveedores OpenID Connect
  • Los tests unitarios cubren los 16 algoritmos en Win32 y Win64
  • Disponible en DelphiMVCFramework 3.5.0-silicon (beta en GitHub en la publicación, 2026-03-30); JWE (RFC 7516) y JWK/JWKS son los siguientes pasos
  • Anunciado entre los temas de ITDevCon 2026 Spring Edition

Comments