Bcrypt en PHP: cómo hashear contraseñas rápido y sin errores
\n\n¿Alguna vez te has preguntado por qué tu sitio en PHP se ralentiza al registrar usuarios? O, peor aún, ¿por qué los hackers logran robar contraseñas de tu base de datos? La respuesta puede estar en cómo usas bcrypt para hashear contraseñas en PHP.
\n\nEsta pregunta es una de las más populares en Stack Overflow (¡miles de visitas!). Y no es de extrañar: la seguridad de las contraseñas es un tema donde un solo error puede costarte tu reputación y a los usuarios sus datos. Pero hoy no solo analizaremos cómo usar password_hash con bcrypt. Hablaremos de optimización y rendimiento. Porque, seamos sinceros, esperar 5 segundos al iniciar sesión no es genial.
Descubramos cómo hacer que el hasheo de contraseñas en PHP no solo sea seguro, sino también rápido. ¡Allá vamos!
\n\n¿Por qué bcrypt? ¿Y por qué no MD5 o SHA?
\n\nMuchos principiantes (y, lamentablemente, algunos "veteranos") todavía usan md5() o sha1(). Es como cerrar una puerta con un pestillo de plástico: parece cerrada, pero basta un soplido para que se abra. MD5 y SHA son hashes rápidos. Demasiado rápidos. Un hacker con una GPU moderna puede probar miles de millones de estos hashes por segundo.
Bcrypt es un enfoque fundamentalmente diferente. Está diseñado específicamente para ser lento. Utiliza una "sal" (datos aleatorios) y un "cost factor" (factor de costo) que obliga al algoritmo a ejecutarse más tiempo. Mientras un hacker calcula un hash bcrypt, podría haber probado un millón de MD5. Por eso bcrypt es el estándar de facto en PHP.
\n\nConceptos básicos: cómo usar bcrypt en PHP correctamente
\n\nA partir de PHP 5.5, tenemos la función mágica password_hash(). Olvídate de agregar la sal manualmente y de llamar a crypt(); todo está hecho por ti.
Así es como se ve el hasheo correcto de una contraseña con bcrypt:
\n\n<?php\n// Hasheamos la contraseña\n$password = 'MySuperSecretPassword123!';\n$hash = password_hash($password, PASSWORD_BCRYPT);\n\necho $hash;\n// Salida: $2y$10$... (cadena de 60 caracteres)\n?>\n\n¡Eso es todo! password_hash genera automáticamente una sal aleatoria y selecciona el cost factor óptimo (por defecto 10). ¿Y cómo verificar la contraseña al iniciar sesión?
<?php\n// Verificamos la contraseña\n$inputPassword = 'MySuperSecretPassword123!';\n$hashFromDB = '$2y$10$...'; // el hash de la base de datos\n\nif (password_verify($inputPassword, $hashFromDB)) {\n echo "¡Contraseña correcta! Bienvenido.";\n} else {\n echo "Contraseña incorrecta. Inténtalo de nuevo.";\n}\n?>\n\nSencillo, ¿verdad? Pero el diablo, como siempre, está en los detalles. Hablemos de lo más importante: el rendimiento.
\n\nOptimización de bcrypt: cómo encontrar el equilibrio entre seguridad y velocidad
\n\nEl parámetro principal que afecta el rendimiento de bcrypt en PHP es el cost factor (costo). Se define como segundo argumento en password_hash() como un array ['cost' => 12].
¿Qué es el cost? Es una escala logarítmica. Cada unidad duplica aproximadamente el tiempo de ejecución.
\n\n- \n
- Cost = 10 (por defecto): ~0.1-0.2 segundos. Rápido, pero para 2024 ya es algo bajo. \n
- Cost = 12: ~0.4-0.8 segundos. Un buen equilibrio para la mayoría de los proyectos. \n
- Cost = 14: ~1.5-3 segundos. Muy seguro, pero los usuarios comenzarán a impacientarse. \n
- Cost = 16+: >5 segundos. Solo si eres un espía o guardas códigos nucleares. \n
¿Cómo elegir el cost ideal? Hay una regla simple: en tu servidor, el hasheo de una contraseña no debe tomar más de 250-500 milisegundos. Esto es imperceptible para el usuario, pero hace que un ataque de fuerza bruta sea demasiado costoso para el hacker.
\n\n