La elección del algoritmo que define la seguridad de tu JWT
Cada vez que un servidor crea un JWT, debe tomar una decisión crítica: ¿qué algoritmo debe firmar este token?
Las dos opciones más comunes son HS256 (simétrico) y RS256 (asimétrico). La mayoría de los desarrolladores eligen uno sin comprender plenamente las compensaciones. Esa elección afecta a todo — desde cómo se gestionan tus secretos hasta qué tan vulnerable es tu sistema a ataques específicos.
Esta guía desglosa ambos algoritmos, explica cuándo usar cada uno y muestra los riesgos de seguridad al elegir incorrectamente.
Qué hace realmente HS256
HS256 significa HMAC-SHA256. Es un algoritmo simétrico, lo que significa que la misma clave secreta se utiliza tanto para firmar como para verificar el token.
El servidor firma el token: HMAC-SHA256(header + payload, SECRET_KEY)
El servidor verifica el token: HMAC-SHA256(header + payload, SECRET_KEY)
La misma clave hace ambos trabajos.
Cuándo funciona bien HS256
- Aplicaciones de servidor único donde solo un servicio firma y verifica tokens.
- Microservicios internos donde todos los servicios son de confianza y comparten el mismo secreto.
- Flujos de autenticación simples donde la distribución de claves no es una preocupación.
El riesgo de HS256
Si la clave secreta es débil, corta o predecible, puede ser forzada por fuerza bruta. Una GPU moderna que ejecute Hashcat puede probar miles de millones de combinaciones HMAC-SHA256 por segundo.
Benchmarks reales:
| Longitud de clave | Tipo de clave | Tiempo de crackeo (RTX 4090) | |---|---|---| | 6 caracteres | minúsculas | menos de 1 segundo | | 8 caracteres | mayúsculas y minúsculas | menos de 1 hora | | 12 caracteres | aleatorio | ~200 años | | 32 bytes | aleatorio | muerte térmica del universo |
Toda la seguridad de HS256 depende de una sola cosa: la robustez de tu clave secreta.
Si usas HS256, tu secreto debe tener al menos 256 bits (32 bytes) de datos criptográficamente aleatorios. Genéralo así:
openssl rand -base64 32
Nunca uses cadenas legibles por humanos como "secret", "password123" o "my-jwt-key".
Qué hace realmente RS256
RS256 significa RSA-SHA256. Es un algoritmo asimétrico, lo que significa que utiliza dos claves diferentes:
- Una clave privada para firmar el token (mantenida en secreto en el servidor de autenticación).
- Una clave pública para verificar el token (puede compartirse con cualquier persona).
El servidor de autenticación firma: BSA-SHA256(header + payload, PRIVATE_KEY)
Cualquier servicio verifica: RSA-SHA256(header + payload, PUBLIC_KEY)
Cuándo funciona bien RS256
- Sistemas distribuidos donde múltiples servicios necesitan verificar tokens pero solo un servicio debe crearlos.
- Integraciones con terceros donde quieres que servicios externos verifiquen tokens sin compartir tu secreto de firma.
- APIs públicas donde la verificación de tokens debe ocurrir sin exponer claves sensibles.
- Flujos de OAuth / OpenID Connect donde los proveedores de identidad publican claves públicas a través de endpoints JWKS.
La ventaja de RS256
Incluso si alguien tiene la clave pública (que está diseñada para ser pública), no pueden falsificar tokens. Solo la clave privada puede firmar. Esto elimina toda una clase de ataques.
La diferencia crítica
HS256 (Simétrico):
Firma: CLAVE_SECRETA
Verifica: CLAVE_SECRETA ← la misma clave
Riesgo: Cualquiera con la clave puede firmar Y verificar
RS256 (Asimétrico):
Firma: CLAVE_PRIVADA ← secreta
Verifica: CLAVE_PÚBLICA ← pública
Riesgo: Solo el poseedor de la clave privada puede firmar
Con HS256, cada servicio que puede verificar tokens también puede falsificar tokens. Si cualquier servicio se ve comprometido, el atacante puede crear tokens para cualquier usuario.
Con RS256, incluso si un servicio de verificación se ve comprometido, el atacante no puede falsificar tokens porque no tiene la clave privada.
El ataque de confusión de algoritmos
Aquí es donde la elección entre HS256 y RS256 se convierte en una vulnerabilidad de seguridad real.
Si un servidor acepta tanto HS256 como RS256, un atacante puede:
- Tomar un token legítimo firmado con RS256.
- Cambiar el encabezado para que diga
"alg": "HS256". - Firmar el token modificado usando la clave pública como el secreto HMAC.
- Enviarlo al servidor.
El servidor ve alg: HS256 y piensa: "Necesito verificar con el secreto compartido". Toma la clave que tiene registrada — que es la clave pública. El atacante firmó con la clave pública. Las firmas coinciden. El token falsificado es aceptado.
Esta es una vulnerabilidad real documentada en CVE-2016-10555 que afecta a la popular biblioteca npm jsonwebtoken.
Cómo prevenirlo
Nunca dejes que el encabezado del token decida qué algoritmo usar.
Tu servidor debe imponer un algoritmo específico:
// Ejemplo de Node.js
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
Codifica el algoritmo de forma rígida. Pon exactamente uno en la lista blanca. Ignora cualquier cosa que diga el encabezado del token.
¿Cuál deberías usar?
Usa HS256 si:
- Tienes un servidor único o un pequeño clúster de confianza.
- Todos los servicios que verifican tokens están bajo tu control directo.
- Puedes garantizar que tu clave secreta es robusta (256 bits aleatorios).
- Quieres una gestión de claves más sencilla.
- El rendimiento es importante (HS256 es más rápido que RS256).
Usa RS256 si:
- Múltiples servicios necesitan verificar tokens.
- Tienes servicios de terceros o APIs externas.
- Usas OAuth o OpenID Connect.
- Quieres publicar claves de verificación sin riesgo de seguridad.
- Necesitas rotar claves sin coordinar con todos los servicios.
- La seguridad es más importante que el rendimiento.
La regla general
Pequeña app interna → HS256 con un secreto fuerte
Cualquier cosa distribuida o pública → RS256
Si no estás seguro, elige RS256. Es más difícil de configurar fatalmente mal.
Inspeccionando el algoritmo de tu JWT de forma segura
Al depurar JWTs, debes verificar qué algoritmo se utilizó. El algoritmo está en el encabezado del token.
Nunca pegues tokens en decodificadores JWT en línea. Tu token contiene credenciales de autenticación. Si el token todavía está activo, le estás entregando una clave en vivo a un servidor de terceros.
Usa un decodificador local del lado del cliente que procese todo en tu navegador sin enviar datos a ninguna parte.
Prueba el Decodificador JWT de FmtDev — todo funciona localement. Tu token nunca sale de tu máquina.
Lista de verificación de seguridad
Independientemente del algoritmo que elijas:
- Impón el algoritmo en el servidor — nunca confíes en el encabezado del token.
- Usa claves robustas — 256 bits aleatorios para HS256, 2048 bits mínimo para RS256.
- Establece tiempos de expiración cortos — minutos u horas, no días.
- Nunca guardes datos sensibles en el payload — no está encriptado.
- Valida todos los claims — verifica
exp,iss,auden cada petición. - Rota las claves periódicamente — especialmente si algún servicio se ve comprometido.
- Decodifica tokens localmente — nunca uses herramientas en línea para tokens activos.