¿Fortalecer el cifrado de archivos basado en contraseña con un cifrado de flujo síncrono más algoritmo de hashing de alta memoria?

1

Entonces, esta es probablemente una pregunta estúpida, pero estoy tratando de entender por qué no se hace lo siguiente para los archivos de descanso cifrados mediante contraseña:

  1. generar una clave AES-256 / salt / iv
  2. tome el mensaje de texto sin formato (digamos un archivo de 50 MB) y cifrelo con las credenciales del paso 1
  3. adjuntar credenciales al mensaje cifrado
  4. permita que el usuario elija una contraseña y la convierta en una clave AES-256 usando algún método estándar
  5. cifre los resultados del paso 3 usando la clave del paso 4, usando AES como un cifrado de flujo síncrono con una forma modificada de modo de realimentación de salida donde:
    1. en lugar de usar el texto simple para alimentar el siguiente bloque, se aplica una función de hashing de alta memoria (como Argon2i) al texto simple, y los resultados de esa operación se incorporan al siguiente bloque
    2. dicha función de hashing usaría parámetros de costos consistentes derivados del tamaño de los datos en 3. (y, por lo tanto, la cantidad de bloques necesarios), más la cantidad deseada de memoria necesaria para descifrar el archivo completo (para que su programa de cifrado lo conozca) desea que se requiera escribir un total de 1 GB de memoria para descifrar este archivo)

A menos que el propio AES-256 estuviera comprometido, parecería que para atacar este archivo, tendría que:

  1. elija una contraseña probable y conviértala a la clave AES-256 correspondiente
  2. use esta clave para descifrar el archivo completo, en cada bloque que calcula el hash Argon2i del bloque anterior (que requiere una cantidad predeterminada de memoria)
  3. cuando llegues al final del archivo, usa los bits al final (que podría ser la clave que necesitas) para descifrar el primer bloque (ya descifrado una vez) y ver si estás correcto

Ya que no se pudo paralizar fácilmente el agrietamiento debido al cifrado de flujo síncrono (cada intento requiere descifrado de mensaje completo), más el hecho de que cada bloque requiere que escriba una cantidad arbitraria de memoria (lo que reduce la amenaza de GPU rápidas / futuras computadoras cuánticas / etc), un método como este no proporcionaría seguridad adicional de manera que el cambio de AES-256 a un AES-512 teórico no (ya que cada contraseña relativamente corta generará una clave AES-512 completa, y puedes verificar si esa suposición es correcta sin descifrar todo el mensaje, por lo que realmente no se gana nada).

Al ajustar los parámetros a su función de hashing (según el tamaño del archivo), debería poder decir "intentar descifrar este archivo de 1 KB requerirá escribir 500 MB de memoria ... e intentar descifrar este archivo de 3 GB También requerirá escribir 500MB de memoria ". Por lo tanto, no sería necesariamente lento para los archivos grandes.

Sé que tiene que haber una razón para que esto no se haga, ¡y me encantaría descubrir en qué me voy mal!

    
pregunta atlantisnova 22.07.2017 - 00:23
fuente

1 respuesta

1

Eso se complica innecesariamente sin una recompensa real. Su interposición de Argon2 en el modo CFB lo hace más costoso, seguro, pero los costos son aditivos , lo que implica que son asociativos ( a + (b + c) = (a + b) + c ), lo que significa que hay no se puede ganar nada realizando todo ese trabajo adicional con Argon2 en ese lugar preciso , si simplemente aumenta los parámetros de Argon2 en el paso # 4, eso es tan bueno y más simple.

Así que tu idea no se ve mejor que:

  1. Genere una Clave de cifrado de datos (DEK) aleatoria;
  2. Para el mensaje de texto sin formato plaintext , calcule un ciphertext = AEAD_encrypt(dek, plaintext) autenticado;
  3. Genera un salt aleatorio;
  4. Genere una Clave de cifrado de clave (KEK) a partir de la contraseña y salt: kek = argon2id(password, salt, argon2_params) , proporcionando parámetros tan costosos como quiera para Argon2id;
  5. Encripta el DEK con KEK: encrypted_dek = AEAD_encrypt(kek, dek) ;
  6. Escriba (salt, argon2_params, encrypted_dek, ciphertext) como su archivo cifrado.

Tenga en cuenta que:

  • No necesita realmente IV / nonces aleatorios aquí, siempre que tenga mucho cuidado de elegir siempre un DEK y sal aleatorios nuevos cada vez que cifre. La propiedad que desea garantizar es que cada clave solo se utilizará para el cifrado de un mensaje.
  • Cuando digo AEAD_encrypt me refiero a un esquema de cifrado autenticado que funciona con mensajes de longitud variable. AES-GCM y ChaCha20 / Poly1305 son dos comunes y populares en estos días. No juegues con los modos y los MAC, usa algo creado previamente.
  • Cuando digo ciphertext y encrypted_dek lo digo en un sentido que incorpora la etiqueta AEAD. Muchas bibliotecas emiten la etiqueta de autenticación por separado de lo que llaman el texto cifrado.
  • El uso de un DEK y KEK separados tiene la propiedad de que puede cambiar la contraseña sin tener que descifrar y volver a cifrar todo el archivo; simplemente puede volver a envolver el DEK encriptado. Si no te importa esto, puedes generar un DEK directamente desde Argon2.
  • Probablemente debería usar Argon2id en lugar de Argon2i. O en realidad, espere hasta que se apruebe el RFC ...
respondido por el Luis Casillas 22.07.2017 - 01:08
fuente

Lea otras preguntas en las etiquetas