Como se menciona en este maravilloso enlace , la forma de obtener un hash PBKDF2 de una contraseña dada por el usuario
- una contraseña (por supuesto),
- a salt (Generador de números aleatorios de seguridad criptográficamente generado).
- recuento de iteraciones (elegido lo suficientemente alto como para ser seguro mientras se equilibra la tolerancia de uso de la aplicación)
- Tamaño de hash (longitud del hash a calcular)
/**
* Computes the PBKDF2 hash of a password.
*
* @param password the password to hash.
* @param salt the salt
* @param iterations the iteration count (slowness factor)
* @param bytes the length of the hash to compute in bytes
* @return the PBDKF2 hash of the password
*/
private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
throws NoSuchAlgorithmException, InvalidKeySpecException
{
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
return skf.generateSecret(spec).getEncoded();
}
Ahora mi pregunta es:
¿Cómo se debe implementar el hash con clave para la contraseña?
Según mi lectura, esta es mi línea de pensamiento. Por favor valide.
-
Mantenga el argumento salt para el método pbkdf2 (en el fragmento de código anterior) en secreto (obténgalo de un HSM altamente seguro en lugar de almacenándolo en la base de datos junto con el hash de contraseña cuando sea necesario).
-
Dado que la sal debe ser aleatoria (para protegerlos de las tablas de arco iris / ataques de diccionario), la sal proporcionada al pbkdf2 debe ser una concatenación de la clave y un byte aleatorio generado desde un CSPRNG.
[sal] = [clave secreta] + [bytes aleatorios de un CSPRNG]
Finalmente, me atreveré a hacer una pregunta tonta (me atreveré a hacerla, ya que el alto número de iteraciones está planteando un problema serio de usabilidad ya que necesitamos autenticar el 90% de los casos de uso en nuestra aplicación)
¿Podemos reducir la cantidad de iteraciones O prescindir de ella ya que hemos agregado una capa adicional de seguridad a través del hash con clave?
P.S : soy consciente del valor que agregan los algoritmos de hash lento al reducir la posibilidad de que las contraseñas se vean comprometidas por los ataques de fuerza bruta. Solo quiero que los expertos comenten sobre el valor agregado de seguridad a través de Keyed Hashing VS que tiene un algoritmo de Slow Hashing con sal no secreta.