Estoy escribiendo una aplicación Java que es necesaria para autenticar localmente a un usuario con una contraseña y luego usar la contraseña para generar una clave AES-256 para el cifrado / descifrado de archivos locales.
Entiendo los principios detrás de todo y lo importante que es la elección del algoritmo adecuado, las rondas de hash y la generación de sal cripto-aleatoria. Teniendo esto en cuenta, utilizo el algoritmo PBKDF2WithHmacSHA256 admitido en Java 8, un valor de sal de 16 bytes generado con SecureRandom de Java y 250 000 rondas de hashing. Mi pregunta está en la implementación, la siguiente es una versión (simplificada) de cómo genero el hash y la clave de los usuarios. El código se acortó por el bien de esta publicación y los valores se codificaron de nuevo para simplificar la publicación.
int iterations = 250000;
String password = "password";
String salt = "salt";
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
char[] passwordChars = password.toCharArray();
KeySpec spec = new PBEKeySpec(passwordChars, salt.getBytes(), iterations, 256);
SecretKey key = factory.generateSecret(spec);
byte[] passwordHash = key.getEncoded();
SecretKey secret = new SecretKeySpec(key.getEncoded(), "AES");
Este código se basa en la concatenación de algunos proyectos Java de código abierto diferentes que he analizado y que también aprovechan el algoritmo PBKDF2 para el hashing de contraseñas, la generación de claves AES o ambos.
Mi pregunta aquí es, ¿es esto realmente seguro? Tengo la sensación de que el uso del mismo valor de SecretKey "clave" para generar el "SecretKey" secreto y generar el hash es incorrecto. Si esto es cierto, ¿alguien puede recomendar el método correcto para aprovechar el algoritmo PBKDF2WithHmacSHA512 para generar un hash de contraseña? y derivar una clave AES?