utiliza AES-CBC
Probablemente deberías usar modo EAX en lugar de CBC. Evitará que se manipulen los datos cifrados (casi sin esfuerzo), y lo protegerá de ciertos casos extremos que afectan al modo CBC. Consulte esta respuesta para una discusión de los diferentes modos.
Los únicos cambios que deberá hacer para hacer esto son usar EAX en lugar de CBC, y necesita usar una clave que sea el doble de grande (una clave de 256 bits si usa AES-128 o 512). clave de bits si está utilizando AES-256). Puede hacer que PBKDF2 genere una clave de cualquier tamaño, pero asegúrese de que la salida sea del tamaño de salida nativo de la función hash, por lo que si desea una clave de 512 bits, use PBKDF2-HMAC-SHA512.
No quiero usar un IV estático (por razones de seguridad) ¿cómo lo hago? ¿Tengo que añadir el IV al archivo y luego, al descifrar, extraerlo?
Puedes almacenar el IV como quieras. Parece común anteponerla a los datos (la preparación es un poco más fácil, ya que puedes leer el archivo desde el principio sin saltar). El formato OpenPGP es bueno porque puede usar otras aplicaciones para leer y escribir los archivos (y el formato ha tenido un mucha atención, por lo que probablemente maneja casos en los que no has pensado todavía). He escrito programas que generan un archivo JSON, con los datos cifrados codificados en base64, y el IV como atributos. Podrías usar XML. Podría distribuir los datos y los metadatos como archivos separados. Realmente depende de ti.
Cuando finaliza el cifrado, se elimina el archivo sin cifrar. ¿Debo tener alguna inquietud de que un atacante pueda recuperar el archivo no cifrado (esta es una aplicación de Android, por lo que la tecnología de almacenamiento subyacente es flash y estoy usando la API estándar para eliminar el archivo) debo implementar una función de eliminación segura o cómo tratar? con esto?
Cuando eliminas un archivo, el sistema de archivos generalmente lo marca como eliminado para que otros archivos puedan escribirse en la parte superior. Para solucionarlo, necesitaría escribir sobre el archivo, pero no estoy seguro de si hay alguna manera de garantizarlo en un sistema de archivos de registro por diario, especialmente si está usando flash (porque los controladores de flash generalmente mueven los bloques para nivelar el desgaste). Podría probablemente hacer esto eliminando el archivo, luego escribiendo un archivo gigante que ocupa todo el espacio libre en el dispositivo, y luego eliminando ese archivo.
La mejor manera de garantizar que los datos privados no se queden sin cifrar en el disco es nunca escribirlos en el disco sin cifrar, pero parece que esa no es una opción para su programa.
Los archivos se cifran utilizando una clave de 256 bits derivada de PBKDF2. PBKDF2 necesita una sal para la cual yo uso un hash de la contraseña del usuario, ¿es esta una mala idea?
Una sal única protegerá su sistema de una gran cantidad de vulnerabilidades, por lo que definitivamente debería usarlo.
¿la sal tiene que ser aleatoria?
No necesariamente tiene que ser aleatorio, pero sí debe ser único. La aleatoriedad suele ser la forma más fácil de obtener valores únicos.
si es así, ¿cómo lo trato? ¿Tengo que adjuntar el salt al archivo para realizar el descifrado?
Almacene la sal de la misma manera que almacena la IV.
Es probable que también desee almacenar el número de iteraciones PBKDF2, para que pueda aumentar el valor predeterminado en el futuro y aún poder descifrar archivos más antiguos. Asegúrese de que su cuenta de iteración es lo suficientemente alta. A modo de comparación, iOS usa PBKDF2 con 10,000 iteraciones al almacenar contraseñas. A menos que su programa se esté ejecutando en una tostadora, no tiene excusa para establecer un valor inferior a ese.