Este método de hash es una construcción hecha a mano que, como casi todas las construcciones hechas a mano, es débil.
En este caso, comete los dos pecados cardinales del hashing de contraseña:
- La función de hash permite ataques paralelos.
- La función de hash es demasiado rápida.
Aquí, si dos usuarios tienen la misma contraseña, terminan con el mismo hash. Esto significa que si el atacante tiene mil hashes de contraseña para trabajar (por ejemplo, volcó la tabla de la base de datos correspondiente a través de alguna inyección de SQL), entonces puede codificar una contraseña potencial y buscar el valor de hash en la tabla: el atacante ataca 1000 contraseñas simultáneamente, por aproximadamente el mismo costo de atacar a uno. Esto es muy malo. Las sales están destinadas a evitar eso, pero esto solo funciona si cada sal se usa para una contraseña de hash, no para todas las contraseñas de hash en un servidor determinado.
En cuanto a la velocidad: una PC básica pasará por varias millones de SHA-512 instancias por segundo. No muchas contraseñas elegidas por el usuario resisten durante mucho tiempo cuando el atacante puede probar millones por segundo ...
La sugerencia de @ paj28 es algo mejor, pero no tan óptima como se podría desear. El uso de un hash del nombre de usuario concatenado con un valor global del servidor (pero distinto de un servidor a otro) garantiza algún tipo de singularidad mundial; sin embargo, si un usuario cambia su contraseña, usará la misma "sal" (ya que está en el mismo servidor y el usuario no cambió los nombres, solo las contraseñas). El atacante que podría obtener los hashes de la contraseña antigua y la nueva aún podrá atacar a ambos en paralelo. Esto es mejor que el método anterior, pero aún no es perfecto.
Además, el problema de la velocidad se mantiene y es lo suficientemente serio como para justificar un anatema en esta propuesta.
Lea esta respuesta para saber cómo debe ser la contraseña hash, y qué conceptos teóricos están trabajando aquí. La respuesta corta es: use bcrypt .