La elección entre HS256 y RS256 se reduce a una pregunta: ¿quién necesita verificar tus tokens? HS256 utiliza una clave secreta compartida para firmar y verificar, lo cual es simple y rápido, pero significa que cada verificador también tiene el poder de crear tokens. RS256 usa una clave privada para firmar y una clave pública separada para verificar, por lo que puedes entregar la clave pública a cualquiera sin darle la capacidad de falsificar. Si entiendes bien esa diferencia, el resto de la decisión se vuelve clara.
La mayoría de las comparaciones se quedan en "simétrico versus asimétrico" y te dejan averiguar cuál necesita realmente tu sistema. Esta guía te ofrece una regla de decisión vinculada a tu arquitectura, diferencias reales a nivel de código, el compromiso de rendimiento que rara vez importa y el único error de configuración que convierte cualquier algoritmo en un agujero de falsificación.
HS256 vs RS256 de un vistazo#
Ambos son algoritmos de firma de JSON Web Token definidos en la especificación JWA (RFC 7518). Protegen lo mismo: la integridad de un token, para que un servidor pueda confiar en que las afirmaciones internas (id de usuario, rol, caducidad) no fueron manipuladas. Se diferencian completamente en cómo se estructura la clave de firma.
| Propiedad | HS256 | RS256 |
|---|---|---|
| Nombre completo | HMAC con SHA-256 | Firma RSA con SHA-256 |
| Tipo de clave | Un secreto compartido (simétrico) | Par de clave privada/pública (asimétrico) |
| Quién puede firmar | Cualquiera con el secreto | Solo el titular de la clave privada |
| Quién puede verificar | Cualquiera con el secreto | Cualquiera con la clave pública |
| Tamaño del token | Firma más pequeña | Firma más grande |
| Velocidad | Muy rápida | Más lenta al firmar, rápida al verificar |
| Mejor para | Un solo servicio de confianza | Múltiples verificadores, terceros |
Consejo clave: con HS256 el verificador y el firmante usan la misma clave, por lo que la capacidad de verificación y la de falsificación son inseparables. Con RS256 están separadas. Ese único hecho impulsa casi todas las decisiones de arquitectura a continuación.
Cómo funciona HS256 (simétrico, secreto compartido)#
HS256 significa HMAC usando SHA-256. HMAC es un hash con clave: se introducen el encabezado del token más el payload y una cadena secreta, y produce una firma fija. Para verificar, el servicio receptor ejecuta exactamente el mismo HMAC con el mismo secreto y comprueba que las firmas coincidan.
Debido a que la firma y la verificación usan un único secreto idéntico, no existe el concepto de lado "público". Cualquiera que pueda verificar un token también puede crear uno válido. Esto está bien cuando un solo servicio emite tokens y los verifica por sí mismo.
Una configuración típica de HS256 en Node se ve así:
import jwt from "jsonwebtoken";
// Firmar
const token = jwt.sign({ sub: "user_123", role: "admin" }, SECRETO_COMPARTIDO, {
algorithm: "HS256",
expiresIn: "15m",
});
// Verificar (mismo secreto)
const claims = jwt.verify(token, SECRETO_COMPARTIDO, { algorithms: ["HS256"] });
El secreto debe ser una cadena larga y aleatoria (al menos 32 bytes para SHA-256). Un secreto débil o adivinable es la forma más común en que las implementaciones de HS256 se rompen, porque un atacante que recupere el secreto puede firmar cualquier cosa.
Cuándo HS256 es la opción correcta#
- Un monolito o un único servicio backend firma y verifica sus propios tokens.
- Un enlace interno entre servicios donde controlas completamente ambos extremos y puedes rotar un secreto compartido de forma segura.
- Quieres el token más pequeño posible y la firma más rápida posible, sin necesidad de exponer la verificación a terceros.
Cómo funciona RS256 (asimétrico, par de claves)#
RS256 es una firma RSA que utiliza SHA-256. Se genera un par de claves: una clave privada que firma y una clave pública que verifica. La clave privada nunca sale de tu servidor de autenticación. La clave pública se puede publicar abiertamente, ya que quien la posee puede verificar tokens pero nunca crearlos.
Esta separación es el punto clave. Puedes distribuir la clave pública a una docena de microservicios, una aplicación móvil o un socio externo, y ninguno podrá falsificar un token incluso si su copia de la clave se filtra.
import jwt from "jsonwebtoken";
// Firmar con la clave privada (solo servidor de autenticación)
const token = jwt.sign({ sub: "user_123", role: "admin" }, PRIVATE_KEY, {
algorithm: "RS256",
expiresIn: "15m",
});
// Verificar con la clave pública (cualquier servicio)
const claims = jwt.verify(token, PUBLIC_KEY, { algorithms: ["RS256"] });
La mayoría de los proveedores de identidad grandes (Auth0, AWS Cognito, Okta, Google y otros que usan OpenID Connect) emiten tokens RS256 y publican sus claves públicas en un endpoint JWKS (una URL .well-known/jwks.json). Tus servicios obtienen la clave pública desde allí y verifican localmente sin necesidad de contactar al servidor de autenticación por cada solicitud.
Advertencia: RS256 solo te protege si mantienes la clave privada en secreto y verificas con la clave pública. Una cantidad sorprendente de errores proviene de configurar accidentalmente un servicio para "verificar" con la clave privada, o de manejar incorrectamente los formatos de clave. En caso de duda, inspecciona el encabezado del token para confirmar que el
alges el esperado.
Cuándo RS256 es la opción correcta#
- Microservicios: muchos servicios necesitan verificar tokens, pero solo uno debe emitirlos.
- Verificación por terceros: un socio o aplicación cliente debe validar tus tokens sin poder crearlos.
- Usas un proveedor de identidad externo u OpenID Connect, donde RS256 más JWKS es el estándar.
- Quieres rotar las claves de firma sin redistribuir un secreto a cada verificador (publica una nueva clave pública, retira la anterior).
ES256 y la familia de algoritmos más amplia#
HS256 y RS256 son los dos que encontrarás con más frecuencia, pero no son las únicas opciones. ES256 (ECDSA usando P-256 y SHA-256) también es asimétrico, como RS256, pero utiliza criptografía de curva elíptica. Ofrece el mismo modelo de firma privada/verificación pública con claves y firmas mucho más pequeñas, lo que mantiene los tokens compactos.
| Algoritmo | Tipo | Notas |
|---|---|---|
| HS256 | Simétrico (HMAC) | Secreto compartido, rápido, confianza única |
| RS256 | Asimétrico (RSA) | Predeterminado ampliamente compatible para OIDC, firmas más grandes |
| ES256 | Asimétrico (ECDSA) | Claves/firmas más pequeñas, moderno, soporte de librerías ligeramente menos universal |
Si necesitas firma asimétrica y te importa el tamaño del token o el rendimiento a escala, vale la pena considerar ES256. Si necesitas la máxima compatibilidad con herramientas existentes y proveedores de identidad, RS256 sigue siendo la opción predeterminada más segura. La lógica de decisión entre ES256 y RS256 es la misma que entre RS256 y HS256, más una verificación de compatibilidad con tus librerías.
La regla de decisión: ¿quién verifica tus tokens?#
Esta es la parte que la mayoría de los artículos omiten. Olvida la velocidad y la longitud de la clave por un momento y responde una pregunta: ¿cuántas partes distintas verifican tus tokens y confías en que todas ellas también puedan firmar?
Usa HS256 si cada verificador también es un firmante de confianza#
Si lo único que verifica tus tokens es el mismo servicio (o un pequeño conjunto de servicios internos totalmente confiables) que los emite, el modelo de secreto compartido es más simple y rápido. No hay problema de distribución de claves porque hay un solo secreto y controlas todos los lugares donde reside. Un monolito clásico con un solo backend es el caso típico para HS256.
Usa RS256 (o ES256) en cuanto la verificación se extiende#
En cuanto un token necesita ser verificado por algo a lo que no quieres darle capacidad de firma, necesitas claves asimétricas. Ejemplos:
- Un frontend o cliente móvil que comprueba la validez de un token.
- Un conjunto de microservicios, donde comprometer cualquier verificador no debería permitir a un atacante falsificar tokens para todo el sistema.
- Un consumidor de API externo o socio que debe confiar en los tokens que emites.
- Cualquier flujo OpenID Connect / OAuth con un proveedor de identidad externo.
La regla en una frase: si el conjunto de verificadores es mayor que el conjunto de partes en las que confías para firmar, usa RS256. Con un secreto compartido, cada verificador es un posible falsificador, y ese riesgo crece con cada servicio que posee el secreto.
Rendimiento: Real, pero normalmente no es el factor decisivo#
HMAC (HS256) es dramáticamente más rápido que RSA (RS256) para el paso de firma, a menudo por un orden de magnitud en pruebas de referencia. La verificación RSA es razonablemente rápida, pero la firma RSA es la operación costosa. Por lo tanto, si firmas enormes volúmenes de tokens en un solo servidor, HS256 gana en CPU.
Para la mayoría de las aplicaciones, esta diferencia es insignificante. Normalmente firmas un token una vez al iniciar sesión y lo verificas muchas veces durante su corta vida. La verificación con RS256 es lo suficientemente rápida como para que el costo por solicitud sea insignificante en comparación con una consulta a la base de datos o un salto de red. Elige tu algoritmo basándote primero en el modelo de confianza, y solo deja que el rendimiento decida si estás firmando a una escala extrema.
Consejo: el tamaño del token es una preocupación más práctica que la CPU. Las firmas RS256 son más grandes, lo que infla cada solicitud que lleva el token en un encabezado. Si eres sensible al ancho de banda y necesitas claves asimétricas, ES256 produce tokens notablemente más pequeños que RS256.
El error que rompe ambos: confiar en el campo alg del header#
Independientemente del algoritmo que elijas, el error de configuración más peligroso es permitir que el propio token decida cómo se verifica. Un JWT lleva un campo alg en su header, y un código de verificación ingenuo lee ese campo y verifica en consecuencia. Los atacantes explotan esto de dos formas conocidas.
Primero, el truco de alg: none: un atacante establece el algoritmo en none, elimina la firma, y algunas bibliotecas aceptan felizmente el token sin firmar como válido. Segundo, el ataque de confusión RS256 a HS256: un servidor configurado para RS256 publica su clave pública, un atacante cambia el header a HS256 y firma un token falsificado usando esa clave pública como si fuera un secreto HMAC. Si el servidor luego verifica HS256 con la clave pública que conoce, el token falsificado pasa.
La solución es la misma en ambos casos y es una línea de intención: fijar el algoritmo aceptado en el verificador. Nunca dejes que el token elija.
// Bueno: el servidor dicta el algoritmo, el token no
jwt.verify(token, PUBLIC_KEY, { algorithms: ["RS256"] });
Siempre pasa una lista explícita de algoritmos permitidos a tu llamada de verificación y asegúrate de que no incluya none. No mezcles HS256 y RS256 en la misma ruta de verificación, porque esa ambigüedad es exactamente lo que necesita el ataque de confusión. Si quieres entender por qué simplemente decodificar un token no te dice nada sobre si es genuino, nuestra guía sobre decodificar versus verificar un JWT explica la diferencia que atrapa a muchos desarrolladores.
Cuando estés depurando un token con cualquiera de los algoritmos, pégalo en nuestro decodificador JWT gratuito para leer el header y confirmar el valor de alg, la expiración y los claims antes de confiar en él. Ver el header real es la forma más rápida de detectar un algoritmo manipulado o no coincidente.
Gestión de Claves: La Diferencia Práctica en el Día a Día#
La elección del algoritmo determina silenciosamente cuánto trabajo de gestión de claves asumes.
Con HS256 tienes un solo secreto. Es fácil de almacenar, pero rotarlo implica actualizar cada lugar que lo contiene al mismo tiempo, y una filtración en cualquier punto es un compromiso total. Guárdalo en un gestor de secretos, nunca en el control de versiones, y trata cualquier servicio que lo contenga como parte de tu núcleo de confianza.
Con RS256 gestionas un par de claves. La rotación es más suave: publica una nueva clave pública (a menudo mediante un endpoint JWKS con un id de clave), empieza a firmar con la nueva clave privada y retira la clave antigua una vez que los tokens pendientes expiren. Los verificadores recogen la nueva clave pública automáticamente. La compensación es tener más partes móviles al inicio, por lo que un servicio pequeño y único rara vez lo necesita.
Para un recorrido más amplio sobre el manejo seguro de tokens, incluyendo almacenamiento, caducidad y qué verificar en cada validación, consulta nuestro tutorial sobre decodificador JWT y seguridad de tokens.
HS256 vs RS256: El resumen#
La decisión entre HS256 y RS256 no se trata realmente de la solidez criptográfica, ya que ambos son seguros cuando se configuran correctamente. Se trata de los límites de confianza. Use HS256 cuando un solo servicio de confianza firme y verifique sus propios tokens y busque simplicidad y velocidad. Recurra a RS256 (o ES256 para tokens más pequeños) en cuanto más partes necesiten verificar de las que confíe para firmar, lo que describe casi cualquier configuración de microservicios, dispositivos móviles, terceros y OpenID Connect.
Sea cual sea su elección, fije el algoritmo en el verificador con una lista explícita de permitidos, nunca acepte none y nunca verifique los tokens de un algoritmo con la clave de otro. Cuando algo parezca sospechoso, decodifique el token y lea su encabezado para saber exactamente con qué está tratando.
Preguntas Frecuentes#
¿Es RS256 más seguro que HS256? No inherentemente. Ambos son criptográficamente sólidos si se configuran correctamente. RS256 es más seguro para sistemas distribuidos porque la clave pública de verificación no puede usarse para falsificar tokens, por lo que filtrarla a muchos verificadores tiene bajo riesgo. HS256 concentra todo el poder en un secreto compartido, lo cual está bien para un único servicio de confianza, pero es más riesgoso cuantos más lugares tengan el secreto.
¿Puedo cambiar de HS256 a RS256 más adelante? Sí, pero planifique un período de transición. Generará un par de claves, comenzará a firmar nuevos tokens con la clave privada RS256 y actualizará los verificadores para aceptar RS256. Evite configurar un servicio para aceptar ambos algoritmos a la vez, ya que esa ambigüedad permite el ataque de confusión de algoritmos. Migre limpiamente y retire la verificación HS256 una vez que los tokens antiguos hayan expirado.
¿Qué algoritmo usan proveedores de identidad como Auth0 y Cognito?
La mayoría de los proveedores de identidad importantes usan RS256 por defecto y publican sus claves públicas en un endpoint JWKS (una URL .well-known/jwks.json). Sus servicios obtienen la clave pública y verifican los tokens localmente. Por eso RS256 es el estándar práctico para cualquier integración OpenID Connect o OAuth con un proveedor externo.
¿Por qué RS256 es más lento que HS256? La firma RSA es matemáticamente más pesada que la operación HMAC que usa HS256, por lo que firmar es notablemente más lento, a menudo por un orden de magnitud en pruebas de rendimiento. La verificación es rápida para ambos. Para la mayoría de las aplicaciones, esta diferencia no importa porque verifica con mucha más frecuencia de la que firma, y el costo de verificación es pequeño comparado con el tiempo de red y base de datos.
¿Qué es el ataque de confusión de algoritmos?
Es una explotación donde un servidor que espera RS256 es engañado para verificar un token HS256 usando su propia clave pública como secreto HMAC. Debido a que la clave pública es, por diseño, conocida por los atacantes, pueden falsificar un token válido. La solución es fijar el algoritmo aceptado en el verificador con una lista blanca y nunca permitir que el encabezado alg del token decida. Puede confirmar el algoritmo declarado de un token con un decodificador JWT gratuito mientras depura.
¿Debería usar ES256 en lugar de RS256? Considere ES256 cuando necesite firma asimétrica pero quiera tokens y claves más pequeños, lo que ayuda al ancho de banda y a clientes móviles. Usa el mismo modelo de firma privada y verificación pública que RS256. La principal desventaja es un soporte ligeramente menos universal de bibliotecas y proveedores, así que verifique que su stack maneje ES256 antes de comprometerse.



