¿Cómo elegir un modo de cifrado AES (CBC ECB CTR OCB CFB)?
¿Cuáles de ellos son los preferidos y en qué circunstancias?
Me gustaría ver la lista de criterios de evaluación para los distintos modos y tal vez una discusión sobre la aplicabilidad de cada criterio.
Por ejemplo, creo que uno de los criterios es el "tamaño del código" para el cifrado y descifrado, lo cual es importante para los sistemas integrados de microcódigo, como los adaptadores de red 802.11. SI el código requerido para implementar CBC es mucho más pequeño que el requerido para CTR (no sé si esto es cierto, es solo un ejemplo), entonces podría entender por qué se preferiría el modo con el código más pequeño. Pero si estoy escribiendo una aplicación que se ejecuta en un servidor y la biblioteca AES que estoy usando implementa tanto CBC como CTR de todos modos, entonces este criterio es irrelevante.
¿Ves lo que quiero decir con "lista de criterios de evaluación y aplicabilidad de cada criterio"?
Esto no está realmente relacionado con la programación, pero sí con el algoritmo.
Considere detenidamente si no puede implementar su propia criptografía.
La fea verdad del asunto es que si hace esta pregunta probablemente no podrá diseñar e implementar un sistema seguro.
Permítanme ilustrar mi punto: imagine que está creando una aplicación web y necesita almacenar algunos datos de la sesión. Puede asignar a cada usuario un ID de sesión y almacenar los datos de la sesión en el servidor en un mapa hash que asigna el ID de sesión a los datos de la sesión. Pero luego tienes que lidiar con este molesto estado en el servidor y si en algún momento necesitas más de un servidor, las cosas se complicarán. Entonces, tiene la idea de almacenar los datos de la sesión en una cookie en el lado del cliente. Por supuesto, lo cifrará para que el usuario no pueda leer ni manipular los datos. Entonces, ¿qué modo deberías usar? Al venir aquí, lees la respuesta principal (perdón por señalarte a myforwik). El primero cubierto, ECB, no es para usted, desea cifrar más de un bloque, el siguiente, CBC, suena bien y no necesita el paralelismo de CTR, no necesita acceso aleatorio, así que no. XTS y las patentes son PITA, por lo que no hay OCB. Al utilizar su biblioteca criptográfica, se da cuenta de que necesita algo de relleno porque solo puede cifrar múltiplos del tamaño del bloque. Elige PKCS7 porque está definido en algunos estándares de criptografía serios. Después de leer en alguna parte que CBC es demostrablemente seguro si se usa con un IV aleatorio y un cifrado de bloque seguro, puede estar tranquilo aunque esté almacenando sus datos confidenciales en el lado del cliente.
Años más tarde, después de que su servicio haya crecido a un tamaño significativo, un especialista en seguridad de TI se comunica con usted para informarle de manera responsable. Ella le está diciendo que puede descifrar todas sus cookies usando un ataque de oráculo de relleno , porque su código produce una página de error si el relleno está roto de alguna manera.
Este no es un escenario hipotético: Microsoft tenía exactamente este defecto en ASP.NET hasta hace unos años.
El problema es que hay muchas trampas con respecto a la criptografía y es extremadamente fácil construir un sistema que parezca seguro para el profano pero que sea trivial de romper para un atacante experto.
Qué hacer si necesita cifrar datos
Para conexiones en vivo, use TLS (asegúrese de verificar el nombre de host del certificado y la cadena del emisor). Si no puede usar TLS, busque la API de más alto nivel que su sistema tiene para ofrecer para su tarea y asegúrese de comprender las garantías que ofrece y, lo que es más importante, lo que no garantiza. Para el ejemplo anterior, un marco como Play ofrece instalaciones de almacenamiento del lado del cliente ; sin embargo, no invalida los datos almacenados después de un tiempo y, si cambia el estado del lado del cliente, un atacante puede restaurar un estado anterior sin que usted se dé cuenta.
Si no hay una abstracción de alto nivel disponible, utilice una biblioteca criptográfica de alto nivel. Un ejemplo destacado es NaCl y una implementación portátil con muchos enlaces de idiomas es Sodium . Al utilizar una biblioteca de este tipo, no es necesario preocuparse por los modos de cifrado, etc., pero debe ser aún más cuidadoso con los detalles de uso que con una abstracción de nivel superior, como nunca usar un nonce dos veces. Para la creación de protocolos personalizados (digamos que desea algo como TLS, pero no sobre TCP o UDP), existen marcos como Noise e implementaciones asociadas que hacen la mayor parte del trabajo pesado por usted, pero su flexibilidad también significa que hay mucho margen de error. , si no comprende en profundidad qué hacen todos los componentes.
Si por alguna razón no puede utilizar una biblioteca criptográfica de alto nivel, por ejemplo porque necesita interactuar con el sistema existente de una manera específica, no hay forma de evitar informarse a fondo. Recomiendo leer Cryptography Engineering de Ferguson, Kohno y Schneier . No se engañe creyendo que puede crear un sistema seguro sin los conocimientos necesarios. La criptografía es extremadamente sutil y es casi imposible probar la seguridad de un sistema.
Comparación de los modos.
Sólo cifrado:
- Modos que requieren relleno : como en el ejemplo, el relleno generalmente puede ser peligroso porque abre la posibilidad de ataques de oráculo de relleno. La defensa más sencilla es autenticar cada mensaje antes de descifrarlo. Vea abajo.
- El BCE cifra cada bloque de datos de forma independiente y el mismo bloque de texto sin formato dará como resultado el mismo bloque de texto cifrado. Eche un vistazo a la imagen cifrada de Tux del BCE en la página de Wikipedia del BCE para ver por qué se trata de un problema grave. No conozco ningún caso de uso en el que el BCE sea aceptable.
- CBC tiene un IV y, por lo tanto, necesita aleatoriedad cada vez que se cifra un mensaje, cambiar una parte del mensaje requiere volver a cifrar todo después del cambio, los errores de transmisión en un bloque de texto cifrado destruyen completamente el texto sin formato y cambian el descifrado del siguiente bloque, el descifrado se puede paralelizar/el cifrado no, el texto sin formato es maleable hasta cierto punto; esto puede ser un problema .
- Modos de cifrado de flujo : estos modos generan un flujo pseudoaleatorio de datos que puede depender o no del texto sin formato. De manera similar a los cifrados de flujo en general, el flujo pseudoaleatorio generado se aplica XOR con el texto sin formato para generar el texto cifrado. Como puede utilizar tantos bits de la secuencia aleatoria como desee, no necesita ningún relleno. La desventaja de esta simplicidad es que el cifrado es completamente maleable , lo que significa que un atacante puede cambiar el descifrado de la forma que desee, como para un texto sin formato p1, un texto cifrado c1 y un flujo pseudoaleatorio r, y el atacante puede elegir una diferencia d tal. que el descifrado de un texto cifrado c2=c1⊕d es p2 = p1⊕d, como p2 = c2⊕r = (c1 ⊕ d) ⊕ r = d ⊕ (c1 ⊕ r). Además, nunca se debe usar el mismo flujo pseudoaleatorio dos veces, ya que para dos textos cifrados c1=p1⊕r y c2=p2⊕r, un atacante puede calcular el xor de los dos textos sin formato como c1⊕c2=p1⊕r⊕p2⊕r= p1⊕p2. Eso también significa que cambiar el mensaje requiere volver a cifrarlo por completo, si un atacante podría haber obtenido el mensaje original. Todos los siguientes modos de cifrado de Steam solo necesitan la operación de cifrado del cifrado de bloque, por lo que, dependiendo del cifrado, esto podría ahorrar algo de espacio (silicio o código de máquina) en entornos extremadamente restringidos.
- CTR es simple, crea una secuencia pseudoaleatoria que es independiente del texto sin formato, se obtienen diferentes secuencias pseudoaleatorias contando desde diferentes nonces/IV que se multiplican por una longitud máxima de mensaje para evitar la superposición, el uso de cifrado de mensajes nonces es posible sin aleatoriedad por mensaje, el descifrado y el cifrado se completan paralelizables, los errores de transmisión solo afectan los bits incorrectos y nada más
- OFB también crea un flujo pseudoaleatorio independiente del texto sin formato, se obtienen diferentes flujos pseudoaleatorios comenzando con un nonce o IV aleatorio diferente para cada mensaje, ni el cifrado ni el descifrado son paralelizables, ya que con CTR el uso de cifrado de mensajes nonces es posible sin mensaje por mensaje. aleatoriedad, como ocurre con la transmisión CTR, los errores solo afectan los bits incorrectos y nada más
- El flujo pseudoaleatorio de CFB depende del texto sin formato, se necesita un nonce diferente o un IV aleatorio para cada mensaje, al igual que con CTR y OFB usando nonces el cifrado de mensajes es posible sin aleatoriedad por mensaje, el descifrado es paralelizable/el cifrado no, los errores de transmisión son completamente Destruye el siguiente bloque, pero solo afecta los bits incorrectos en el bloque actual.
- Modos de cifrado de disco : estos modos están especializados para cifrar datos debajo de la abstracción del sistema de archivos. Por razones de eficiencia, cambiar algunos datos en el disco sólo debe requerir la reescritura de como máximo un bloque de disco (512 bytes o 4 kib). Están fuera del alcance de esta respuesta ya que tienen escenarios de uso muy diferentes a los demás. No los use para nada excepto para el cifrado de disco a nivel de bloque . Algunos miembros: XEX, XTS, LRW.
Cifrado autenticado:
Para evitar ataques de relleno de Oracle y cambios en el texto cifrado, se puede calcular un código de autenticación de mensaje (MAC) en el texto cifrado y solo descifrarlo si no ha sido manipulado. Esto se llama encrypt-then-mac y debe preferirse a cualquier otro orden . Excepto en muy pocos casos de uso, la autenticidad es tan importante como la confidencialidad (la última de las cuales es el objetivo del cifrado). Los esquemas de cifrado autenticados (con datos asociados (AEAD)) combinan el proceso de dos partes de cifrado y autenticación en un modo de cifrado de bloque que también produce una etiqueta de autenticación en el proceso. En la mayoría de los casos, esto da como resultado una mejora de la velocidad.
- CCM es una combinación simple del modo CTR y CBC-MAC. El uso de cifrado de dos bloques por bloque es muy lento.
- OCB es más rápido pero está sobrecargado de patentes. Sin embargo , para el software gratuito (como en la libertad) o no militar, el titular de la patente ha concedido una licencia gratuita .
- GCM es una combinación muy rápida pero posiblemente compleja de modo CTR y GHASH, un MAC sobre el campo Galois con 2^128 elementos. Su amplio uso en importantes estándares de red como TLS 1.2 se refleja en una instrucción especial que Intel ha introducido para acelerar el cálculo de GHASH.
Recomendación:
Teniendo en cuenta la importancia de la autenticación, recomendaría los siguientes dos modos de cifrado de bloques para la mayoría de los casos de uso (excepto para fines de cifrado de disco): Si los datos se autentican mediante una firma asimétrica, utilice CBC; de lo contrario, utilice GCM.
No se debe utilizar ECB si se cifra más de un bloque de datos con la misma clave.
CBC, OFB y CFB son similares, sin embargo, OFB/CFB es mejor porque solo necesita cifrado y no descifrado, lo que puede ahorrar espacio en el código.
CTR se utiliza si desea una buena paralelización (es decir, velocidad), en lugar de CBC/OFB/CFB.
El modo XTS es el más común si está codificando datos accesibles aleatoriamente (como un disco duro o RAM).
OCB es, con diferencia, el mejor modo, ya que permite el cifrado y la autenticación en una sola pasada. Sin embargo, existen patentes al respecto en EE. UU.
Lo único que realmente debe saber es que ECB no debe usarse a menos que solo esté cifrando 1 bloque. Se debe utilizar XTS si está cifrando datos a los que se accede aleatoriamente y no una secuencia.
- SIEMPRE debe utilizar IV únicos cada vez que cifra, y deben ser aleatorios . Si no puede garantizar que sean aleatorios , utilice OCB, ya que solo requiere un nonce , no un IV , y existe una clara diferencia. Un nonce no reduce la seguridad si las personas pueden adivinar el siguiente; un IV puede causar este problema.