Explicación del CBC Bit Flipping
El cifrado no significa que tus datos estén a salvo de manipulaciones.
Muchos desarrolladores cometen este error. Piensan que si un atacante no puede leer los datos, no puede cambiarlos. Esto es un error. La criptografía trata la confidencialidad y la integridad como dos tareas distintas.
El ataque de CBC Bit Flipping demuestra esto. Un atacante puede cambiar tus datos sin conocer tu clave secreta.
Así es como funciona:
AES no cifra los datos en una sola pieza grande. Divide los datos en bloques de 16 bytes. En modo CBC, estos bloques se encadenan. La salida cifrada del primer bloque se mezcla con el texto plano del segundo bloque.
Esta cadena crea una debilidad durante el descifrado. Para obtener el texto original del Bloque 2, el servidor lo descifra y lo combina con el texto cifrado del Bloque 1.
Un atacante puede explotar esto:
- El atacante intercepta tu tráfico cifrado.
- No conocen la clave, por lo que los datos parecen texto sin sentido.
- Cambian bits específicos en el texto cifrado del Bloque 1.
- Envían estos datos alterados a tu servidor.
- Cuando el servidor lo descifra, el cambio en el Bloque 1 altera el cálculo matemático para el Bloque 2.
El atacante no necesita leer el mensaje. Simplemente invierte bits para cambiar el resultado final.
Considera una aplicación web antigua que utiliza cookies cifradas para las sesiones. Una cookie podría contener:
userid=994;role=user;
Un atacante intercepta esta cookie e invierte bits en el texto cifrado. Envía muchas solicitudes hasta que el servidor acepta una. Debido a que el servidor solo comprueba si los datos se pueden descifrar, procesa el texto modificado. De repente, la cadena descifrada dice:
userid=994;role=admi;
El atacante ahora tiene acceso de administrador. Nunca leyó la clave ni la cookie original.
El error es asumir que el cifrado garantiza la integridad.
- La confidencialidad evita que la gente lea los datos.
- La integridad evita que la gente cambie los datos.
Para solucionar esto, utiliza cifrado autenticado como AES-GCM. Este crea una etiqueta criptográfica. Esta etiqueta actúa como un sello. Si un atacante cambia incluso un solo bit, el sello se rompe. El servidor rechaza los datos inmediatamente.
Si debes usar CBC, utiliza una arquitectura Encrypt-then-MAC. Crea un código de autenticación para el texto cifrado y verifícalo antes de comenzar el descifrado.
Los datos secretos no siempre son datos confiables. Demuestra siempre que tus datos no han sido alterados antes de usarlos para tomar decisiones.
Explicación del Bit-Flipping en CBC: Por qué el cifrado por sí solo no garantiza la integridad
Cuando pensamos en el cifrado, solemos pensar en la confidencialidad. Queremos asegurarnos de que nadie más pueda leer nuestros datos. Pero hay otro pilar fundamental de la seguridad de la información: la integridad.
La integridad garantiza que los datos no hayan sido alterados durante el tránsito o el almacenamiento. El problema es que mucha gente asume erróneamente que si un mensaje está cifrado, es imposible de modificar sin que se note.
Aquí es donde entra en juego el ataque de bit-flipping (cambio de bits) en el modo de cifrado CBC (Cipher Block Chaining).
¿Qué es el modo CBC?
En el modo CBC, cada bloque de texto plano se combina (mediante una operación XOR) con el bloque de texto cifrado anterior antes de ser cifrado.
El proceso de cifrado se puede representar así: $C_i = E_k(P_i \oplus C_{i-1})$
Donde:
- $P_i$ es el bloque de texto plano actual.
- $C_{i-1}$ es el bloque de texto cifrado anterior (para el primer bloque, se usa el Vector de Inicialización o IV).
- $E_k$ es la función de cifrado con la clave $k$.
- $C_i$ es el bloque de texto cifrado resultante.
Para el descifrado, el proceso es el inverso: $P_i = D_k(C_i) \oplus C_{i-1}$
Donde $D_k$ es la función de descifrado.
La vulnerabilidad: El ataque de Bit-Flipping
Observa la ecuación de descifrado: $P_i = D_k(C_i) \oplus C_{i-1}$.
Fíjate en el término $C_{i-1}$. El bloque de texto plano $P_i$ depende directamente del bloque de texto cifrado anterior $C_{i-1}$ a través de una operación XOR.
Si un atacante intercepta el texto cifrado y modifica un bit en el bloque $C_{i-1}$, ese cambio se reflejará directamente en el bloque de texto plano $P_i$ al momento de descifrarlo.
Aunque modificar $C_{i-1}$ corromperá completamente el bloque $P_{i-1}$ (haciéndolo ilegible), el atacante puede manipular $P_i$ de una manera muy precisa.
La matemática detrás del ataque
Si un atacante cambia $C_{i-1}$ por un nuevo valor $C'_{i-1}$, el nuevo texto plano $P'_i$ será:
$P'i = D_k(C_i) \oplus C'{i-1}$
Como sabemos que $D_k(C_i) = P_i \oplus C_{i-1}$, podemos sustituirlo:
$P'i = (P_i \oplus C{i-1}) \oplus C'{i-1}$ $P'i = P_i \oplus (C{i-1} \oplus C'{i-1})$
Esto significa que el atacante puede elegir $C'_{i-1}$ para que $P'_i$ sea exactamente lo que él desea. Si quiere que $P'_i$ sea $P_i \oplus \Delta$ (donde $\Delta$ es el cambio deseado), simplemente debe establecer:
$C'{i-1} = C{i-1} \oplus \Delta$
Un ejemplo práctico
Imagina que una aplicación utiliza CBC para cifrar una cookie de sesión que contiene los siguientes datos:
user=guest;admin=0
Supongamos que este texto plano se divide en bloques. El atacante quiere cambiar admin=0 a admin=1.
- El atacante identifica en qué bloque de texto cifrado se encuentra la cadena
admin=0. - Supongamos que esa cadena está en el bloque $P_i$.
- El atacante calcula la diferencia ($\Delta$) entre
admin=0yadmin=1. - El atacante modifica el bloque de texto cifrado anterior $C_{i-1}$ aplicando esa diferencia mediante XOR.
Cuando el servidor reciba el mensaje y lo descifre, el bloque $P_{i-1}$ se verá como basura (ruido aleatorio), pero el bloque $P_i$ ahora dirá user=guest;admin=1. Si la aplicación solo verifica el valor de admin y no valida la integridad de todo el mensaje, el atacante habrá ganado acceso de administrador.
¿Cómo prevenirlo?
El error fundamental es confiar únicamente en el cifrado para la integridad. Para protegerse contra ataques de bit-flipping, se debe utilizar Cifrado Autenticado (Authenticated Encryption).
Existen dos formas principales de lograr esto:
1. Usar un MAC (Message Authentication Code)
Puedes usar un esquema de "Encrypt-then-MAC". Primero cifras el mensaje y luego generas un código de autenticación (como un HMAC) utilizando una clave distinta. Al recibir el mensaje, primero verificas el HMAC; si el texto cifrado ha sido alterado, el HMAC no coincidirá y el mensaje se descartará antes de intentar descifrarlo.
2. Usar modos de cifrado AEAD
La forma más moderna y recomendada es utilizar modos de cifrado que ya incluyen la autenticación, conocidos como AEAD (Authenticated Encryption with Associated Data).
Ejemplos comunes incluyen:
- AES-GCM (Galois/Counter Mode)
- ChaCha20-Poly1305
Estos algoritmos no solo cifran los datos, sino que también generan una "etiqueta de autenticación" (authentication tag). Si un solo bit del texto cifrado es modificado, el proceso de descifrado fallará automáticamente, garantizando que la integridad se mantenga.
Conclusión
El cifrado proporciona confidencialidad, pero no garantiza la integridad. En el modo CBC, un atacante puede manipular el texto plano de forma predecible mediante un ataque de bit-flipping. Nunca confíes en el cifrado solo para proteger la integridad de tus datos; utiliza siempre mecanismos de autenticación como HMAC o modos AEAD.