¿por qué es necesario el relleno en el modo de cifrado CBC? ¿Es para que los bloques tengan la misma longitud de n bits?
Sí. Los cifrados de bloque (como AES) requieren que el bloque de entrada tenga una cierta longitud (128 bits en el caso de AES), y CBC utiliza bloques del texto plano como entrada al cifrado de bloque (después de un paso XOR). Los cifrados de bloque no están diseñados para funcionar en un bloque parcial.
¿Por qué es probable que esta implementación del modo CBC utilizando el relleno proporcione un oráculo de relleno a un atacante?
Todos los diseños modernos de encriptación incluyen un "código de autenticación de mensaje" (MAC) para evitar que un atacante manipule el texto cifrado y el IV. Los MAC son como firmas digitales en los datos: si alguien intenta cambiar el texto cifrado de alguna manera, entonces el código de descifrado puede detectar que se alteró porque la firma ya no será válida.
Desafortunadamente, algunas implementaciones usan MAC de manera incorrecta (o no lo hacen). Esto permite a un atacante manipular el texto cifrado de varias maneras y observar su efecto en el código de descifrado. ¿Se estrella? ¿Da un error específico? Etc.
Un tipo particular de error que podría observarse es un error de relleno. Esto ocurrirá cuando el texto cifrado se descifre y el código de descifrado descubra que no se rellenó correctamente (por ejemplo, no es válido PKCS7 relleno ). Esto permite que un atacante envíe textos cifrados modificados y descubra si el texto sin formato correspondiente se rellena correctamente o no.
Por ejemplo, supongamos que el atacante desea descifrar el tercer bloque de un texto cifrado de cuatro bloques. Si el atacante envía un texto cifrado modificado que contiene solo los primeros tres bloques, entonces el código de descifrado esperará que el tercer bloque contenga relleno. El código de descifrado ahora revelará al atacante si el tercer bloque se considera correctamente o no rellenado (ya que si no lo es, devolverá un error de relleno). ¡Observe cómo el atacante acaba de aprender información sobre el texto simple! Esto puede ser una pequeña porción de información, pero el código de descifrado nunca debe revelar información como esta a un atacante.
El atacante puede continuar, sin embargo, y en realidad "descifrar" el bloque byte por byte. Durante el descifrado, el tercer bloque se calcula como AES-decrypt(key, ciphertext-block-3) XOR ciphertext-block-2
. Al realizar cambios en el segundo bloque, el atacante puede afectar lo que el tercer bloque desencripta!
El atacante comienza modificando el último byte del segundo bloque, probando diferentes valores hasta que el descifrado ya no genere un error de relleno. Una vez que el atacante encuentra uno que funciona, el atacante puede deducir (con buena probabilidad) que esto causó que el tercer bloque se descifre a algo que termina con 01
. ¿Por qué? Debido a que cualquier bloque que termina con 01
se considera correctamente rellenado, de acuerdo con PKCS7 .
Ahora para las matemáticas: sabemos que el último byte de AES-decrypt(key, ciphertext-block-3)
XOR'd con el byte que encontramos = 01
. Por lo tanto, 01
XOR'd con el último byte que encontramos nos dará el último byte de AES-decrypt(key, ciphertext-block-3)
. Como recordamos el último byte original del segundo bloque, podemos XOR con el último byte de AES-decrypt(key, ciphertext-block-3)
, y esto nos dará el último byte del texto simple del tercer bloque.
Con este conocimiento, el atacante puede proceder de manera similar para cada byte anterior del tercer bloque, dividiendo cada byte de uno en uno.