Si hago un hash de las contraseñas antes de almacenarlas en mi base de datos, ¿es suficiente para evitar que alguien las recupere?
Debo señalar que esto se refiere únicamente a la recuperación directamente de la base de datos, y no a cualquier otro tipo de ataque, como la forzadura bruta de la página de inicio de sesión de la aplicación, el keylogger en el cliente y, por supuesto, el criptoanálisis de la goma (o hoy en día deberíamos llamarlo "Criptoanálisis de chocolate").
Por supuesto, cualquier forma de hash no evitará esos ataques.
Las contraseñas almacenadas en una base de datos como valores hash pueden recuperarse mediante el cálculo por fuerza bruta de los hash o mediante el uso de tablas rainbow (que son específicas del algoritmo utilizado).
Una tabla rainbow se crea como una serie de valores precalculados para un archivo de diccionario o, más comúnmente, para cada combinación de un determinado conjunto de caracteres [a-z, A-Z, 0-9] es un ejemplo común.
Básicamente, pueden acelerar el descifrado de una contraseña al permitir que el valor hash se busque en la tabla en lugar de requerir que el atacante cree el hash para cada contraseña. Las tablas Rainbow para los algoritmos de contraseñas más comunes (por ejemplo, NTLM, MD5, etc.) se pueden encontrar en línea, lo que hace que sea bastante sencillo acceder a grandes volúmenes de ellas.
Hay varias formas de mejorar la seguridad de los hashes almacenados en la base de datos.
La primera es utilizar un valor de sal por usuario, este valor se almacena en la base de datos junto con la contraseña con hash. No se pretende que sea secreto, sino que se utiliza para ralentizar el proceso de fuerza bruta y hacer que las tablas rainbow sean poco prácticas de utilizar.
Otra adición que he visto a esto es añadir también lo que se llamaba un valor de pimienta. La teoría aquí es que en algunas circunstancias la base de datos puede estar comprometida pero el código de la aplicación no, y en esos casos esto podría mejorar la seguridad. Sin embargo, introduce problemas si hay varias aplicaciones que utilizan la misma base de datos de contraseñas.
Una tercera forma de ayudar a mejorar la seguridad de las contraseñas es utilizar una función de contraseña lenta, esto no tendrá un gran impacto en los usuarios individuales, pero ralentizará enormemente a un atacante en el descifrado de las contraseñas recuperadas de la base de datos. Hay más información sobre este enfoque aquí.
Las contraseñas deben estar siempre cifradas, pero eso no significa que no haya posibilidad de ataques de fuerza bruta. Deben aplicarse medidas adicionales en relación con el almacenamiento y la gestión de las contraseñas de los usuarios. Recomiendo este artículo de Solar Designer sobre este tema: http://php-security.org/2010/05/26/mops-submission-10-how-to-manage-a-php-applications-users-and-passwords/index.html.
Dependiendo del algoritmo que utilices la respuesta es probablemente no.
En primer lugar, debes salarlas, lo que significa básicamente añadir o anteponer algún texto a la contraseña.
Luego debes usar un algoritmo fuerte (md5 no es suficiente)