Lo mejor es no reinventar la rueda. Pero, entiendo, en el mundo de PHP puede ser difícil encontrar un componente de alta calidad que ya lo haga (incluso estoy bastante seguro de que los marcos implementan tales cosas y sus implementaciones ya están probadas, sólidas, revisadas por código, etc. )
Usa PBKDF2 o Bcrypt si puedes . Está hecho para eso.
Justificación: ambos algoritmos pueden hacer que el proceso de hashing sea arbitrariamente lento, que es exactamente lo que desea cuando se usan contraseñas de hashing (las alternativas más rápidas significan una fuerza bruta más fácil). Idealmente, debe ajustar los parámetros para que el proceso se vuelva más y más lento con el tiempo en el mismo hardware, mientras se lanza un hardware nuevo y más rápido.
Si no puede, al menos no use MD5 / SHA1. Nunca. Olvídate de eso . Utilice SHA512 en su lugar, por ejemplo. Usa sal también.
Justificación: MD5 y SHA1 son demasiado rápidos. Si el atacante tiene acceso a su base de datos que contiene los hashes y tiene una máquina (ni siquiera particularmente poderosa), forzar una contraseña con fuerza bruta es rápido y fácil. Si no hay sales, las posibilidades de que el atacante encuentre la contraseña real aumenta (lo que podría causar un daño adicional si la contraseña se reutilizara en otro lugar).
En PHP 5.5.0 y posterior, use password_hash
y password_verify
.
Justificación: llamar a una función proporcionada por el marco es fácil, por lo que se reduce el riesgo de cometer un error. Con esas dos funciones, no tiene que pensar en parámetros diferentes como el hash. La primera función devuelve una sola cadena que luego puede almacenarse en la base de datos. La segunda función usa esta cadena para la verificación de contraseña.
Protégete de la fuerza bruta . Si el usuario envía una contraseña incorrecta cuando ya envió otra contraseña incorrecta hace 0.01 segundos, es una buena razón para bloquearla. Si bien los seres humanos pueden escribir rápido, probablemente no puedan ser tan rápidos.
Otra protección sería establecer un límite de fallas por hora. Si el usuario envió 3600 contraseñas incorrectas en una hora, 1 contraseña por segundo, es difícil creer que se trata de un usuario legítimo.
Justificación: si sus contraseñas están codificadas de forma insegura, la fuerza bruta puede ser muy efectiva. Si las contraseñas se almacenan de forma segura, la fuerza bruta sigue desperdiciando los recursos del servidor y el ancho de banda de la red, lo que causa un menor rendimiento para los usuarios legítimos. La detección de fuerza bruta no es fácil de desarrollar y acertar, pero para cualquier sistema que no sea pequeño, vale la pena.
No solicite a sus usuarios que cambien sus contraseñas cada cuatro semanas. Esto es extremadamente molesto y disminuye la seguridad, ya que fomenta la seguridad basada en post-it.
Justificación: la idea de que obligar a cambiar las contraseñas cada n semanas protege al sistema de la fuerza bruta es errónea. Los ataques de fuerza bruta suelen tener éxito en segundos, minutos, horas o días, lo que hace que los cambios mensuales de contraseña sean irrelevantes. Por otro lado, los usuarios son malos para recordar contraseñas. Si, además, necesitan cambiarlos, intentarán usar contraseñas muy simples o simplemente anotarán sus contraseñas en los post-it.
Auditar todo, siempre. Almacene inicios de sesión, pero nunca almacene contraseñas en el registro de auditoría. Asegúrese de que el registro de auditoría no pueda modificarse (es decir, puede agregar datos al final, pero no modificar los datos existentes). Asegúrese de que los registros de auditoría estén sujetos a copias de seguridad periódicas. Idealmente, los registros deberían almacenarse en un servidor dedicado con accesos muy restrictivos: si otro servidor es pirateado, el atacante no podrá borrar los registros para ocultar su presencia (y la ruta tomada durante el ataque).
No recuerde la credencial de usuario en las cookies, a menos que el usuario solicite hacerlo (la casilla de verificación "Recordarme" debe estar desmarcada de forma predeterminada para evitar errores humanos).