Tiempo de lectura: 4 minutos
Imagen: Bruno Carbonel Garcés

Un cifrado puede ser irrompible y, aun así, rendir su secreto: sin tocar la llave, basta con repetirle al sistema una pregunta de «sí o no» hasta que cede. El método se llama oráculo de relleno (padding), y aquí vamos a comprenderlo.

AES, el cifrado que resguarda casi todo lo que viaja por internet, se considera —hasta donde sabemos— inquebrantable: dar con su llave a ciegas exigiría 21282^{128} tanteos, más que átomos hay en la galaxia. Y, pese a ello, en 2014 alguien leyó cookies de sesión cifradas en pleno HTTPS sin la llave.

La debilidad no reside en el cifrado, sino en todo lo que lo rodea. Bastan tres ingredientes: una unidad (el bloque), una forma de encadenar esos bloques (el modo CBC) y un descuido (el relleno). Y una sola operación, XOR, que lo cose todo.

1. El bloque y la llave

Diagrama que muestra cómo el mensaje de texto "Hello, world!!!" se codifica en 16 bytes hexadecimales con relleno y se carga en el estado AES como una rejilla 4x4 llenada por columnas
Imagen: Bruno Carbonel Garcés

Un bloque son 16 bytes: el texto se vuelve bytes, se agrupa de a 16 y se carga en la rejilla 4×4 que AES revuelve.

Todo es binario: ocho bits forman un byte, y el texto se vuelve bytes mediante una codificación (H = 0x48). Un bloque es un trozo de tamaño fijo, y AES siempre usa 16 bytes. Dentro del cifrado, esos 16 bytes se acomodan en una rejilla 4×4 (el estado) que se mezcla durante diez rondas hasta volverla irreconocible.

La llave es un secreto compartido que sirve para cifrar y descifrar: cifrado simétrico. (En HTTPS, el saludo asimétrico tipo RSA solo sirve para acordar esa llave simétrica; luego AES hace todo el trabajo.) Para esta historia, trata AES como una black box: transforma un bloque en otro de forma determinista y solo reversible con la llave. El punto clave: sin la llave no se puede invertir, y AES no se rompe en este ataque — se le da la vuelta por los costados.

La herramienta para dársela es XOR (), que compara dos bits y responde «¿son diferentes?». Su rasgo decisivo es que aplicarlo dos veces con el mismo valor lo deshace:

a⊕︎k⊕︎k=aa \oplus k \oplus k = a

De ahí la regla de oro que conviene memorizar: si conoces dos de tres valores ligados por un XOR, el tercero sale con un solo XOR.

2. Encadenar: el modo CBC

Diagrama del descifrado en modo CBC
Imagen: Bruno Carbonel Garcés

Cada bloque se descifra a un valor intermedio secreto y se combina por XOR con el bloque cifrado anterior. El primero usa un IV aleatorio.

AES solo transforma un bloque; para un mensaje largo hace falta un modo que encadene. CBC mezcla cada bloque con el cifrado anterior. Al descifrar, definimos el valor intermedio

Ii=DK(Ci)I_i = D_K(C_i)

y entonces el texto en claro es

Pi=Ii⊕︎Ci1P_i = I_i \oplus C_{i-1}

Tres hechos lo son todo: IiI_i es fijo y secreto (depende solo de CiC_i y la llave); Ci1C_{i-1} son bytes que el atacante puede reescribir; así que controla un lado de un XOR cuyo otro lado es un valor fijo desconocido. Es la regla de oro esperando a ser usada.

3. El relleno y el oráculo

Como los bloques van completos, el último se rellena (PKCS#7: si faltan N bytes, cada uno vale N; colas válidas: 01, 02 02, 03 03 03…). Al descifrar, el servidor comprueba si el relleno respeta la regla; si no, reacciona distinto: un error, una conexión cortada, un tiempo de respuesta diferente. Esa reacción observable desde fuera es el oráculo.

No hay un «bit reservado» que anuncie corrupción: es un comportamiento que se filtra sin querer, un canal lateral. «Oráculo de relleno» significa que el servidor, sin proponérselo, contesta: «¿esto descifró a un relleno válido? Sí o no.»

4. El momento de la revelación

Diagrama del oráculo de relleno: el atacante elige C'[15] y, combinado con el secreto I[15], obtiene el byte candidato P'[15]; cuando el oráculo confirma el relleno válido (0x01), se recupera el byte secreto mediante I[15] = C'[15] XOR 0x01
Imagen: Bruno Carbonel Garcés

Dos valores conocidos revelan el tercero: tú elegiste C′[15] y el oráculo confirma P′[15] = 0x01, así que I[15] sale con un solo XOR.

El atacante coloca delante del bloque objetivo CiC_i un bloque CC’ que controla, y envía CCiC’ \,|\, C_i. El servidor calcula

P=Ii⊕︎CP’ = I_i \oplus C’

y solo informa si el relleno es válido.

  1. Barre el último byte C[15]C'[15] de 0x00 a 0xFF (256 intentos como mucho).
  2. Para el valor que da relleno válido, sabe que P[15]=0x01P'[15] = \texttt{0x01}. Conoce dos de tres, así que despeja: Ii[15]=C[15]0x01I_i[15] = C'[15] \oplus \texttt{0x01}.
  3. Lo convierte en texto real con el bloque genuino anterior: Pi[15]=Ii[15]Ci1[15]P_i[15] = I_i[15] \oplus C_{i-1}[15].
  4. Se desplaza a la izquierda forzando 02 02, luego 03 03 03, etc., hasta los 16 bytes.

No es una búsqueda binaria que parte el espacio a la mitad, sino un barrido de «correcto / incorrecto». El modelo mental limpio:

1 bit entra por pregunta → acumulas ~256 → sale 1 byte → repites byte a byte hasta que el mensaje entero es tuyo.

El costo total es 256 × (número de bytes): lineal con el tamaño del mensaje, ridículo frente a los 21282^{128} de la llave.

5. ¿Por qué funciona, y cómo se cierra?

El atacante nunca invierte AES: DKD_K sin la llave es un muro. Pero CBC pega un XOR reversible (con bytes que él controla) a la salida del cifrado, y el sistema mide y reporta una propiedad del texto descifrado: su relleno. El error fatal es reportar —contarle a un desconocido un hecho sobre el texto ya descifrado—. Esa es la frontera que se cruza, entre «descifra a algo bien formado» y «viene de quien tiene la llave». Cifrar da confidencialidad, no integridad.

No fue teoría: en 2014, POODLE (CVE-2014-3566) usó exactamente este oráculo en SSL 3.0 —forzando la caída desde TLS— para robar cookies de sesión byte a byte. La cura es el cifrado autenticado (AEAD: AES-GCM, ChaCha20-Poly1305): una etiqueta de integridad se verifica antes de mirar el relleno, de modo que un mensaje manipulado se rechaza sin filtrar ni un sí/no. Es el «principio criptográfico de la fatalidad (doom)«: si descifras antes de autenticar, estás condenado.

La lección

Fugas minúsculas, más la posibilidad de repetir, más un atacante que adapta cada pregunta, suman compromiso total. Diseñar con seguridad es, en buena medida, asegurarse de que el sistema nunca conteste las preguntas del atacante —ni siquiera con una sola palabra.