el hashing de contraseñas es una compensación: usted hace que la función sea más lenta (mediante el uso de muchas iteraciones), lo que hace que los ataques y el uso normal sean más caros. Aceptas gastar más CPU en la tarea de verificar una contraseña porque sabes que también hará que el atacante gaste más CPU en la tarea de descifrar una contraseña. Una función de hashing de contraseñas decente ofrece un parámetro de "costo" que le permite configurar la lentitud de la función al mejor nivel, es decir, el más caro que puede tolerar, para sus recursos disponibles y su carga promedio.
Si hace el hash X veces, entonces el uso de X será más lento, tanto para usted como para el atacante. En la práctica, esto significa que debe reducir el número de iteraciones de la función en un factor de X , para mantener el cálculo dentro de su propio presupuesto de hardware, y esto anula exactamente cualquier ganancia de seguridad. Por lo tanto, desde ese punto de vista, su mecanismo propuesto es simplemente neutral a la seguridad (excepto que aumenta la complejidad de la implementación, que es, en igualdad de condiciones, algo malo).
Todavía hay un punto interesante a considerar, que es la aleatoriedad de X . Supongamos que genera X al azar, entre 5 y 15. En promedio, X será igual a 10; al validar una contraseña (correcta), deberá calcular la función de hashing aproximadamente 10 veces (en promedio). Sin embargo, para decidir que una contraseña es incorrecta, debes ir al 15.
Allí podríamos decir: hey, eso es bueno! El defensor (su servidor), en su uso normal, valida las contraseñas en su mayoría correctas (los usuarios tienden a escribir sus contraseñas correctamente (*)), mientras que el atacante, en su ataque de diccionario, intentará contraseñas incorrectas la mayor parte del tiempo. Así que el atacante gastará 1.5 veces más CPU en cada intento de contraseña que el defensor. ¡Acabamos de ganar un factor de 1.5x sobre el atacante! ¿No está hinchado?
No es así. El atacante es consciente de su mecanismo "aleatorio X " y organizará su ataque en consecuencia. Es decir, hará un hash de las palabras en su diccionario con 5 invocaciones de hashing, registrando los valores de hash (en la RAM, aquí solo estamos hablando de millones de valores de hash, o tal vez un par de billones, nada de extremo). Si uno de los valores de hash se ajusta, está bien, el atacante ha ganado. De lo contrario, calculará una invocación de hash adicional sobre cada valor registrado e intentará nuevamente. Y así sucesivamente.
De esa manera, el atacante también logrará el mismo tipo de eficiencia que el defensor: él también descifrará una contraseña con un costo (en promedio) 10 veces el costo de invocar la función hash. Por lo tanto, nuevamente, la ventaja de seguridad del X aleatorio se anula.
(*) Esta es una noción bastante optimista.
Resumen: el factor X adicional, aleatorio o no, no aumenta la seguridad. Implementado correctamente, tampoco debería disminuirlo mucho, pero como hace que el código sea más complejo y también hace que la carga sea menos predecible, solo puedo recomendar ese mecanismo adicional.