Bcrypt en PHP: cómo hashear contraseñas rápido y sin errores

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Bcrypt en PHP: cómo hashear contraseñas de forma correcta y rápida

\n\n

Si alguna vez te has preguntado "How do you use bcrypt for hashing passwords in PHP?", no estás solo. Esta pregunta en Stack Overflow acumula miles de visitas, y con razón. El hashing de contraseñas es la base de la seguridad de cualquier aplicación web, y bcrypt sigue siendo uno de los algoritmos más fiables y populares. En este artículo, veremos cómo usar bcrypt en PHP, cómo configurarlo para máximo rendimiento y cómo evitar errores comunes.

\n\n

¿Por qué bcrypt? Porque es resistente a ataques de fuerza bruta gracias a su "sal" incorporada y su complejidad ajustable. Pero, ¿cómo lograr que tu sitio no se ralentice en cada inicio de sesión? De eso hablaremos.

\n\n

¿Qué es bcrypt y por qué es mejor que MD5 o SHA1?

\n\n

Aclaremos esto de inmediato: nunca uses MD5 o SHA1 para hashear contraseñas. Estos algoritmos están diseñados para ser rápidos, no para ser seguros. Bcrypt, en cambio, está diseñado específicamente para ser lento. Utiliza un cost factor (factor de costo) que determina cuántas iteraciones de hashing se ejecutarán. Cuanto mayor sea el cost factor, más tiempo tomará calcular el hash y más difícil será para un atacante descifrar la contraseña.

\n\n

En PHP, trabajar con bcrypt es muy sencillo gracias a las funciones password_hash() y password_verify(). Aparecieron en PHP 5.5 y desde entonces se han convertido en el estándar de facto.

\n\n

Cómo usar bcrypt en PHP: ejemplo básico

\n\n

Empecemos con lo simple. Así es como registras a un usuario y guardas su contraseña:

\n\n
<?php\n// Registro de usuario\n$password = "MiSuperP@ss123";\n$hash = password_hash($password, PASSWORD_BCRYPT);\n\n// Guardamos $hash en la base de datos (ej. en el campo password_hash)\necho $hash; // Mostrará algo como $2y$10$...\n?>
\n\n

Y así es como verificas la contraseña al iniciar sesión:

\n\n
<?php\n// Inicio de sesión del usuario\n$loginPassword = "MiSuperP@ss123";\n$storedHash = "$2y$10$..."; // desde la base de datos\n\nif (password_verify($loginPassword, $storedHash)) {\n    echo "¡Contraseña correcta!";\n} else {\n    echo "Contraseña incorrecta.";\n}\n?>
\n\n

Sencillo, ¿verdad? Pero el diablo está en los detalles. Analicemos el cost factor.

\n\n

Ajuste del cost factor: equilibrio entre seguridad y velocidad

\n\n

Por defecto, PASSWORD_BCRYPT usa un cost factor = 10. Esto significa 2^10 = 1024 iteraciones. En un servidor moderno, esto toma aproximadamente 0.1–0.2 segundos. Parece poco, pero si tienes 1000 inicios de sesión simultáneos, el tiempo comenzará a aumentar.

\n\n

¿Cómo elegir el cost factor óptimo? Hay una regla simple: debe ser tal que el hashing de una contraseña tome como máximo 0.5 segundos en tu servidor. Puedes probarlo con la función password_hash() usando diferentes valores.

\n\n

Aquí tienes un ejemplo de prueba de rendimiento:

\n\n
<?php\n$password = "contraseña_prueba";\n$times = [];\n\nfor ($cost = 8; $cost <= 14; $cost++) {\n    $start = microtime(true);\n    password_hash($password, PASSWORD_BCRYPT, ['cost' => $cost]);\n    $times[$cost] = microtime(true) - $start;\n}\n\nprint_r($times);\n?>
\n\n

En un hosting compartido típico, un cost factor de 10–12 será óptimo. Si tienes un servidor potente, puedes subirlo a 13–14. Pero no te excedas: un cost factor demasiado alto puede hacer que tu servidor consuma todos los recursos en hashing durante un ataque.

\n\n

Optimización del rendimiento de bcrypt en PHP

\n\n

Ahora pasemos a lo más interesante: cómo hacer que bcrypt sea más rápido sin sacrificar seguridad. Aquí tienes varias estrategias comprobadas:

\n\n

1. Almacenamiento en caché de resultados

\n

Si un usuario ingresa la contraseña correcta, ¿por qué volver a hashearla en cada solicitud? Puedes almacenar en caché el resultado por un tiempo breve (por ejemplo, 5 minutos) usando Redis o Memcached. Esto es especialmente

Blogs

Book Recommendations