Necesitas ambos una sal y una IV cuando haces ... dos acciones distintas, una que necesita una sal y la otra una IV. Ese es tu caso aquí.
The salt se relaciona con convertir una contraseña en una clave secreta . Eso es lo que se usa en su código de ejemplo: PBKDF2 es una función de derivación de claves basada en contraseña . Como cualquier cosa que use contraseñas, PBKDF2 necesita lentitud configurable (ese es el parámetro "2000") y también unicidad , que la sal otorga. Este es un subcaso de hashing de contraseñas, que se se explica allí .
El IV es necesario para el cifrado real. CBC mode es un algoritmo secuencial, en el que cada bloque de datos se XORedea primero con la salida. del tratamiento del bloque anterior. Debe comenzar en algún lugar ... por lo que el IV es el "bloque anterior" arbitrario que se usará para el primer bloque.
En términos generales, el modo CBC requiere un IV que es uniformemente aleatorio y no puede ser predicho por un atacante que está en posición de elegir parte de los datos que se van a cifrar (el ataque BEAST en SSL es de ese tipo). Sin embargo, los problemas solo surgen cuando se utiliza la misma clave al menos dos veces. Por lo tanto, los dos siguientes trucos pueden ser aplicables, y evitar la necesidad de transmitir un IV a lo largo del archivo cifrado:
- PBKDF2 se puede usar para generar una salida de longitud configurable. Es posible generar con PBKDF2 suficientes bytes para la clave y la IV.
- Se utiliza un IV fijo convencional (por ejemplo, "todos ceros").
Ambos métodos son válidos solo si la clave de cifrado específica se usa solo una vez. Esto significa que si se usa la misma contraseña para cifrar dos archivos, entonces se debe generar un nuevo salt aleatorio para cada archivo. Esto implica que si la transformación de contraseña a clave es computacionalmente costosa (y debería serlo), y muchos archivos deben cifrarse con la misma contraseña, entonces el costo total puede volverse prohibitivo.
Si se usa la misma sal para varios archivos (con la misma contraseña) (*), la consecuencia es que se usará la misma clave para todos estos archivos, lo cual está bien ... Siempre y cuando cada archivo también tenga su propia IV. Así que el IV debe almacenarse de alguna manera en el encabezado del archivo. Por otro lado, si todos los archivos usan el mismo salt, entonces, ¿tal vez pueda mutualizar el espacio de almacenamiento para ese salt?
El método genérico, seguro es utilizar un IV aleatorio (generado a partir de un PRNG criptográficamente sólido) para cada ejecución de encriptación, independientemente de cómo se obtuvo la clave. Esto evita hacer suposiciones implícitas sobre el proceso de generación de claves y con qué frecuencia ocurre en el protocolo general. Además, esto permite la mutualización de la transformación de contraseña a clave si muchos archivos se deben cifrar como un proceso por lotes con la "misma contraseña": siempre que cada archivo tenga su propio IV aleatorio, la misma clave (derivada de una vez a partir de la contraseña, con un sal) se puede aplicar de forma segura para todos. Esto es de alguna manera lo que sucede en TLS (versión 1.1 y más): todos los registros en un determinado La conexión se encripta con la misma clave, pero cada registro obtiene su propio IV, y esto es seguro (en TLS 1.0, cada registro obtiene su propio IV al copiarlo desde el final del registro encriptado anterior, que es vulnerable a BEAST porque estos Los IV son predecibles a través de la observación; en TLS 1.1+, cada registro tiene un nuevo aleatorio IV específico.
(*) NUNCA reutilice un valor de sal para contraseñas distintas. Nunca.