Modos de encriptación AES explicados Por qué GCM supera a CBC en la mayoría de los casos (y en qué situaciones no)
AES solo no es una elección completa de algoritmo. El modo — CBC, CTR, GCM, ECB — determina todo sobre si tu cifrado realmente es seguro. Aquí está el desglose práctico que necesitan los desarrolladores.
Cuando la documentación te dice que «use AES-256», eso es una recomendación incompleta. AES es un cifrado por bloques — encripta exactamente un bloque de 128 bits a la vez. El modo de operación es lo que determina cómo AES maneja datos reales más largos de 16 bytes, y qué tan bien protege a los usuarios de atacantes que pueden observar o manipular el cifrado. Hacer esto mal es cómo terminas con datos «encriptados» que revelan la estructura de tus archivos o con un sistema vulnerable a ataques de inversión de bits.
La especificación completa del algoritmo se ve así AES-256-GCM o AES-128-CBC — tamaño de clave seguido del modo. Este artículo explica qué hace cada modo, por qué GCM es la opción por defecto y en qué casos podrías tener una razón legítima para elegir algo diferente.
Primero, por qué ECB es un meme y no solo una broma
ECB (Electronic Codebook) es el modo básico. Cada bloque de 16 bytes de texto plano se encripta independientemente con la misma clave. Esto significa que bloques de texto plano idénticos producen bloques de cifrado idénticos.
La demostración clásica es el penguin de Linux (Tux) encriptado con ECB. La imagen se encripta bloque por bloque, pero como grandes áreas de la imagen son de un color uniforme, la versión encriptada aún muestra claramente la forma de un penguin. La encriptación es matemáticamente válida — el dato está desordenado — pero la patrón se conserva.
En la práctica, esto importa cada vez que tu texto plano tenga repeticiones: filas de una base de datos con un prefijo común, encabezados de archivos, campos rellenados. ECB revela la estructura. No hay caso legítimo para usar ECB en código nuevo. Si estás manteniendo código que utiliza ECB: reemplázalo.
Los modos que vale la pena conocer
CBC — el modo que más código antiguo utiliza
El encriptado por cadenas de bloques XORa cada bloque de texto plano con el bloque de cifrado anterior antes de encriptarlo. Esto elimina el problema del patrón de ECB — bloques de texto plano idénticos producen cifrados diferentes porque la cadena de bloques hace que cada bloque dependa de lo que vino antes.
CBC requiere un vector de inicialización (IV) — un valor de 16 bytes aleatorio que inicia la cadena para el primer bloque. El IV no necesita ser secreto, pero debe ser aleatorio y debe transmitirse junto con el cifrado.
El problema con CBC: proporciona confidencialidad pero no integridad. Un atacante que puede modificar el cifrado en tránsito puede invertir bits específicos en la salida descifrada de forma predecible. Esto es la base de los ataques de oráculo de relleno, que han roto sistemas reales (POODLE, BEAST, Lucky Thirteen). Si usas CBC sin un código de autenticación separado (Message Authentication Code) para verificar la integridad, estás expuesto. El patrón se llama «encriptar-entonces-MAC» — encripta primero, luego HMAC el cifrado, y verifica el MAC antes de descifrar. Hacer esto mal es un error clásico.
CBC también es secuencial — no puedes paralelizar la encriptación (cada bloque depende del bloque de cifrado anterior) y la descifrado es solo parcialmente paralelizable.
CTR — comportamiento de un cifrado por flujo derivado de un cifrado por bloques
El modo de contador convierte AES en un cifrado por flujo. En lugar de encriptar el texto plano directamente, encripta valores sucesivos de contador y XORa el resultado con el texto plano. Esto significa que el modo CTR no necesita relleno (funciona con datos de longitud arbitraria), es completamente paralelizable en ambas direcciones y permite acceso aleatorio a cualquier posición en el cifrado para descifrar.
CTR utiliza un nonce (número usado una vez) en lugar de un IV completo. El nonce debe ser único por mensaje para una clave dada — reutilizar un nonce con la misma clave revela el XOR de los dos textos planos, lo cual es catastrófico. A diferencia de CBC, CTR tampoco tiene protección de integridad. La misma historia: necesita encriptar-entonces-MAC si deseas resistencia a manipulaciones.
CTR tiene sentido cuando necesitas propiedades de cifrado por flujo — archivos grandes, descifrado con acceso aleatorio, escenarios de alto rendimiento donde la paralelización importa — y cuando manejas la capa de MAC por separado.
GCM — cifrado autenticado en un paso
El modo Galois/Counter (GCM) es CTR más una etiqueta de autenticación integrada (GHASH). Obtienes confidencialidad e integridad en una sola operación. La etiqueta de autenticación — típicamente de 128 bits — permite al receptor verificar que el cifrado no ha sido manipulado antes de descifrarlo. Sin paso separado de HMAC, sin riesgo de ordenar mal «encriptar-entonces-MAC».
GCM también soporta Datos autenticados adicionales (AAD) — datos que se autentican pero no se encriptan. Esto es útil para encabezados, metadatos o cualquier dato que necesite protección de integridad pero no necesite confidencialidad. El AAD se verifica junto con el cifrado contra la etiqueta de autenticación.
El nonce para GCM es de 96 bits (12 bytes) por defecto. Al igual que CTR, el reuso del nonce es fatal — reutilizar un nonce con la misma clave bajo GCM revela tanto el texto plano como la clave de autenticación (H), rompiendo completamente la seguridad. Genera siempre nonces con un generador de números aleatorios criptográficamente seguro; nunca deriva los nonces de contadores secuenciales a menos que tengas un esquema cuidadoso de contador distribuido.
GCM es paralelizable y no requiere relleno. Es la recomendación estándar en TLS 1.3, el protocolo Signal y en la mayoría de las bibliotecas criptográficas modernas. Si estás escribiendo código nuevo, GCM es tu elección por defecto.
Comparación de modos
| Modo | Autenticado | Paralelizable | Necesita relleno | Riesgo de reutilización de nonce/IV | Veredicto |
|---|---|---|---|---|---|
| ECB | No | Sí | Sí | N/A (sin IV) | Nunca use |
| CBC | No (agrega MAC) | Encriptar: No / Descifrar: Sí | Sí | Moderado | Solo para sistemas antiguos |
| CTR | No (agrega MAC) | Sí | No | Crítico — reutilización = revelación del texto plano | Uso nicho |
| GCM | VS Code | Sí | No | Crítico — reutilización = ruptura total | Elección por defecto |
AES-256-GCM en Node.js
Aquí tienes una implementación completa de encriptación/descifrado usando el módulo integrado de Node — sin dependencias requeridas: crypto Algunas cosas importantes sobre este código:
const crypto = require('crypto');
const ALGORITHM = 'aes-256-gcm';
const KEY_LENGTH = 32; // 256 bits
const NONCE_LENGTH = 12; // 96 bits — GCM default
const TAG_LENGTH = 16; // 128-bit auth tag
function encrypt(plaintext, key) {
const nonce = crypto.randomBytes(NONCE_LENGTH);
const cipher = crypto.createCipheriv(ALGORITHM, key, nonce, {
authTagLength: TAG_LENGTH,
});
const encrypted = Buffer.concat([
cipher.update(plaintext, 'utf8'),
cipher.final(),
]);
const tag = cipher.getAuthTag();
// Prepend nonce + tag to ciphertext for storage/transmission
return Buffer.concat([nonce, tag, encrypted]);
}
function decrypt(ciphertext, key) {
const nonce = ciphertext.subarray(0, NONCE_LENGTH);
const tag = ciphertext.subarray(NONCE_LENGTH, NONCE_LENGTH + TAG_LENGTH);
const data = ciphertext.subarray(NONCE_LENGTH + TAG_LENGTH);
const decipher = crypto.createDecipheriv(ALGORITHM, key, nonce, {
authTagLength: TAG_LENGTH,
});
decipher.setAuthTag(tag);
// Throws if auth tag doesn't match — do not catch this silently
return Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8');
}
// Generate a key (do this once; store it securely)
const key = crypto.randomBytes(KEY_LENGTH);
const message = 'Hello, authenticated encryption.';
const ciphertext = encrypt(message, key);
console.log('Encrypted:', ciphertext.toString('hex'));
const plaintext = decrypt(ciphertext, key);
console.log('Decrypted:', plaintext); // Hello, authenticated encryption.
El nonce se genera de forma fresca en cada llamada de encriptación
- es criptográficamente seguro. No reemplázalo con un contador a menos que entiendas el problema de unicidad distribuida. —
crypto.randomBytesEl nonce y la etiqueta de autenticación se almacenan junto con el cifrado - — deben viajar con los datos encriptados. El nonce es público; la etiqueta es pública. Solo la clave es secreta. — se lanza en caso de falla de autenticación
decipher.final()— este es el comportamiento correcto. No cágtalo silenciosamente y devuelva un texto plano parcial. El fallo de autenticación significa que los datos fueron manipulados o la clave es incorrecta. La gestión de claves es la parte difícil- te da una buena clave, pero dónde la guardas y cómo la rotas importa más que la elección del algoritmo. Usa un gestor de secretos, no una constante codificada. —
crypto.randomBytes(32)¿Quieres probar los modos de encriptación de forma interactiva?
IO Tools’ herramienta de encriptación/descifrado de AES te permite encriptar y descifrar con modos CBC y GCM en el navegador — útil para verificar interoperabilidad o depurar una integración. Para generar una clave criptográficamente segura de 256 bits, usa el Generador de claves de AES IV y nonce: las reglas que realmente importan.
El mal uso de nonces/IV causa más brechas en el mundo real que la elección del algoritmo. Las reglas:
Genera siempre nonces/IVs con un generador de números aleatorios criptográfico (CSPRNG)
- en Node, —
crypto.randomBytes()en Java. Noos.urandom()en Python,SecureRandom. No una marca de tiempo. No un contador incrementando a menos que sea un contador global cuidadosamente gestionado con garantías estrictas de unicidad.Math.random()El reuso del nonce en GCM rompe completamente la autenticación - — con la misma clave y nonce, GCM expone la clave de autenticación H. Un atacante puede entonces forjar etiquetas de autenticación para cifrados arbitrarios. Esto no es teórico: el ataque Forbidden explota esto y ha sido usado contra implementaciones reales. El reuso del IV en CBC es menos catastrófico pero aún malo
- — los ataques de texto plano elegido se vuelven factibles. En la práctica, genera siempre un IV fresco por mensaje. Nunca deriva un nonce a partir del contenido del mensaje
- — los nonces determinísticos que dependen de datos predecibles crean patrones predecibles. Usa aleatoriedad. Cuándo CBC o CTR sigue siendo la opción correcta
GCM no es siempre la solución:
Interoperabilidad con sistemas antiguos
- — si estás integrando con un sistema que solo habla AES-CBC, estás usando CBC. Documenta claramente la necesidad de MAC y implementa correctamente (encriptar-entonces-MAC con HMAC-SHA256). Entornos restringidos sin aceleración de GHASH en hardware
- — el paso de autenticación de GCM utiliza GHASH, que es más pesado computacionalmente que una operación básica de cifrado por bloques en hardware sin aceleración dedicada. Algunos dispositivos embebidos donde CTR+CMAC está disponible pero GHASH no puede justificar el uso de CTR. Encriptación por flujo de archivos muy grandes donde necesitas descifrado con acceso aleatorio
- — la propiedad de acceso aleatorio de CTR es útil cuando necesitas descifrar la posición N sin leer las posiciones 0 hasta N-1. GCM técnicamente permite esto, pero verificar la etiqueta de autenticación requiere procesar todo el cifrado primero, lo que anula el propósito. Cifrado de disco
- — el cifrado completo de disco utiliza el modo XTS (no cubierto aquí), no GCM, porque XTS está diseñado para sectores de tamaño fijo y acceso aleatorio. GCM está destinado al cifrado de mensajes, no al cifrado de sectores. AES-256-GCM
La versión breve
Usa para código nuevo. Genera un nonce aleatorio de 12 bytes por cada llamada de encriptación. Almacena el nonce y la etiqueta de autenticación junto con el cifrado. Trata los fallos de verificación de autenticación como errores, no como advertencias — nunca devuelvas un texto plano cuando GCM indique que los datos son inválidos. Si estás revisando código existente de CBC: verifica que se implemente correctamente el encriptar-entonces-MAC, revisa que los IVs sean aleatorios (no reutilizados, no secuenciales) y planifica una ruta de migración a GCM cuando el periodo de mantenimiento lo permita. El CBC con HMAC correcto no está roto — simplemente tiene más trampas que GCM.
ECB: simplemente reemplázalo. No existe un camino de auditoría que termine con «ECB está bien aquí».
8 de junio de 2026
También te puede interesar
Instalar extensiones
Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas
恵 ¡El marcador ha llegado!
Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!
Herramientas clave
Ver todo Los recién llegados
Ver todoActualizar: Nuestro última herramienta was added on Jun 26, 2026
