Hay cuatro problemas con solo iterar md5 una y otra vez, sin importar cuántas veces lo hagas.
Potencia de cálculo en el tiempo
El primer gran problema aquí es que, tal como está escrito, no se escala con el tiempo para mantenerse seguro a medida que las computadoras se vuelven más rápidas. Lo que es seguro hoy se romperá en momentos en las computadoras del mañana.
Los algoritmos modernos y seguros, como bcrypt y scrypt, se han incorporado en el ajuste para que el algoritmo pueda ajustarse automáticamente para ser más lento a medida que las computadoras atacantes se vuelven más rápidas. Dado que bcrypt también es gratuito y aún es una simple función para ti, no hay ninguna buena razón para no usarlo.
Ahora, tienes el inicio de una estructura de escala integrada en tu código. Sería fácil refactorizar que ejecutar el hash md5 un número arbitrario de veces, de modo que pueda ajustarlo para que sea más lento con el tiempo. Pero eso no es suficiente.
Diseñado para el fracaso
El segundo problema es que md5 es una opción fundamentalmente mala para un hash criptográfico porque fue diseñado específicamente para ser rápido . El propósito de md5 es verificar o comparar rápidamente archivos grandes. Para lograr esto, el hash necesita poder ser computado de manera rápida y eficiente. Esto significa que los objetivos de implementación y diseño del algoritmo están completamente en desacuerdo con el almacenamiento de contraseñas. Las posibilidades de que en algún momento encontremos una manera de calcular un hash md5 que sea órdenes de magnitud más rápido de lo que podemos hacer actualmente son órdenes de magnitud más altas de lo que podremos hacer lo mismo para sha1 o bcrypt.
Degeneración
El tercer problema es que los algoritmos de hash en general tienden a degenerate a medida que los iteras. Para entender esto, tome el texto original suministrado por el usuario. El tamaño conceptual de este texto es ilimitado . Aquí hay un número infinito de valores posibles. Una vez que hemos procesado el texto una vez con md5, hemos bajado a 2 128 número de valores posibles ... aún muy grandes, pero ya no están sin límites. Pero vamos a completar esto otra vez. md5 es bueno, pero no es perfecto . Esos 340 undecillion entradas potenciales tendrán algunas colisiones y producirán una cantidad de resultados que están cerca, pero todavía algo menos que, 2 128 . A medida que continúe iterando, encontrará más colisiones, hasta que finalmente termine con un número que, aunque aún es grande, es significativamente menor que el espacio conceptual con el que pensaba que estaba trabajando.
Ciclos
Finalmente, el cuarto problema es que algunas de sus entradas potenciales originales darán como resultado ciclos : el número de valor 12345 hashes a 98743, que hashes a 67321, que vuelve a 12345, y así sucesivamente. En otras palabras, algunas entradas se desplazarán por el mismo conjunto pequeño de valores hash, y si los vuelve a hacer no será de utilidad . De hecho, cuantas más veces ejecute el hash, mayor será la probabilidad de que una entrada original determinada termine en un ciclo.
Esto se remonta al diseño de md5. Un hash criptográfico podría diseñarse para minimizar (no eliminar completamente, pero al menos minimizar) la degeneración y los fenómenos del ciclo, pero no fue una preocupación en absoluto para md5.
Conclusión
Cualquiera de estas razones es suficiente para no usar md5. Hay otras opciones perfectamente buenas disponibles, y generalmente usan la misma interfaz, por lo que elegir una diferente no es difícil. En algunas plataformas, es tan fácil como cambiar un valor de enumeración que se pasa a la función "createhash". Ponga las tres razones juntas, y continuar usando md5 es una locura.