Cifrar archivos de forma segura con la contraseña proporcionada por el usuario

3

Actualmente estoy intentando crear un editor de texto RTF basado en escritorio (seguro) escrito para node-webkit usando node.js. Basado en algunas respuestas que leí aquí, como ¿Cómo puedo convertir de forma segura una contraseña de" cadena "a una clave utilizada en AES? y ¿Número recomendado de iteraciones al usar PKBDF2-SHA256? , entre otros, he creado el siguiente sistema. Sin embargo, no estoy seguro de la manera en que he combinado estos algoritmos, y esperaba que alguien pudiera revisar el sistema.

En la primera inicialización de la aplicación:

  1. Genere 1024 bytes pseudoaleatorios criptográficamente seguros ( k )
  2. Genere 256 más ^ como una sal ( s )
  3. Pedir la contraseña de usuario ( p )
  4. Estire p usando PBKDF-2 usando s como sal, 64 K rondas (n = número de rondas) a una longitud de 512 bytes (longitud = l) ( P ) (toma un poco más de un segundo en mi sistema)
  5. Encripte k utilizando AES-CBC con P como clave ( K )
  6. Almacenar s||n||l||K en el disco

Para cifrar y luego guardar un archivo nuevo:

  1. Pedir la contraseña de usuario ( p )
  2. Leer s||n||l||K desde el disco
  3. Como en el paso 3 anterior, estire p a P usando s , n y l del paso 2
  4. Descifrar K usando P
  5. Use k para cifrar datos de archivos usando AES CBC; guardar en disco

Las posibles preocupaciones (teniendo en cuenta que se supone que esto se puede usar en una computadora portátil / computadora de escritorio moderna) incluyen:

  • números mágicos (64K, 512, 1024)
  • no IV (no estoy seguro si es necesario)
  • algo sobre alguna combinación de algoritmos
  • otro error estúpido
pregunta Vivek Ghaisas 25.01.2015 - 00:12
fuente

1 respuesta

5

Mis observaciones son las siguientes:

  • Almacenar el valor de l no tiene sentido. Debe almacenar n en su lugar. Debe tener en cuenta que PBKDF2 no produce secuencias diferentes para valores diferentes de l , sino que extiende la secuencia por más tiempo.
  • La generación de 1024 bytes para k y 512 bytes para P parece impar, ya que AES no acepta más de una clave de 256 bits (32 bytes).
  • En el paso 5 del cifrado, usted dice que k está cifrado usando AES-CBC, pero no menciona cómo se selecciona el IV. Esto no es muy importante aquí, ya que k no tendrá bloques duplicados, pero es una buena práctica usar el modo de cifrado correctamente.
  • En el paso 5 del descifrado, nuevamente mencionas AES-CBC sin especificar el IV. Esto es fundamental: la selección incorrecta de la IV puede romper completamente el sistema.
  • No proporciona autenticidad en el archivo ni en los metadatos almacenados. Esto es realmente importante, porque AES-CBC es maleable (es decir, el texto cifrado se puede modificar de manera que afecte al texto plano, sin necesidad de conocer la clave) y su construcción podría ser particularmente susceptible.

Su construcción general está realmente bien, pero falta los detalles que separan una construcción segura de una débil.

Así es como lo haría:

  • sea p la contraseña del usuario.
  • deje que kd (clave de datos) sea un valor aleatorio de 128 bits.
  • permita que s (sal) sea un valor aleatorio de 128 bits.
  • sea c el recuento de iteraciones, por ejemplo, 1,000,000.
  • deje que km (clave maestra) y ka (clave de autenticidad) se calculen como dos 16 Byte (128 bits) mitades de PBKDF2 (p, s, c, 32) , es decir, PBKDF2 de la contraseña de usuario y sal, con el recuento de iteraciones definido y una longitud de salida de 32 bytes.
  • deje que k'd (clave de datos cifrados) se calcule como AES (k d , k m ) , utilizando AES de 128 bits en modo ECB.
  • deje que IV sea el vector de inicialización para usar al cifrar los datos del archivo.
  • sea Q (metadatos) los valores concatenados s | c | k ' d | IV .
  • sea aQ el registro de autenticidad para Q , definido como H (Q, k a ) , donde H es una función hash criptográfica en una construcción HMAC, por ejemplo HMAC-SHA256.
  • almacene Q y aQ en el encabezado del archivo.

Dado que se están utilizando claves de 128 bits, y AES tiene un tamaño de bloque de 128 bits, solo se necesita cifrar un bloque al calcular k'd y, por lo tanto, AES en modo ECB es seguro; la complejidad adicional de usar CBC u otro modo no es necesaria.

Proporcionar un registro de autenticidad para los metadatos ayuda a evitar que un atacante "ajuste" los parámetros necesarios para descifrar el archivo. Lo más importante es que proporciona autenticidad del IV, que es un objetivo primordial para la modificación, ya que si se le asigna un valor, el primer bloque de texto sin formato también se borrará con ese valor al descifrarlo. Esta propiedad es conocida como maleabilidad. Para plaintexts parcialmente conocidos (por ejemplo, estructurados), esto puede tener efectos devastadores.

Debería poder extrapolar el resto del proceso de cifrado y descifrado de archivos desde aquí. Una adición que haría es calcular un hash HMAC de los datos cifrados, luego almacenarlos en el encabezado, para garantizar la autenticidad de los datos cifrados.

    
respondido por el Polynomial 25.01.2015 - 01:02
fuente

Lea otras preguntas en las etiquetas