Todos los artículos

Bcrypt: por qué las contraseñas se hashean lento y no rápido

Si alguna vez viste un hash bcrypt empezando por $2y$ en un proyecto PHP y te preguntaste por qué no es $2a$ como en otros lenguajes, hay una historia detrás: en 2011 se descubrió un bug en la implementación crypt_blowfish de PHP que manejaba mal ciertos bytes con el bit alto activado, produciendo hashes distintos a los de una implementación correcta. En vez de arreglar $2a$ silenciosamente y romper hashes ya generados, PHP introdujo el prefijo $2y$ para marcar "esta implementación específica, ya corregida" — por eso password_hash() en PHP genera $2y$ hasta hoy.

Por qué la velocidad perjudica la seguridad de las contraseñas

Si un atacante roba una base de datos de hashes, intenta recuperar la contraseña original por fuerza bruta. Con una función rápida como SHA-256, el hardware moderno prueba miles de millones de combinaciones por segundo. Si hashear una sola contraseña toma deliberadamente 100 milisegundos, la fuerza bruta se vuelve órdenes de magnitud más lenta y costosa.

Qué es el cost factor

Bcrypt tiene un parámetro "cost" que fija el número de rondas internas como potencia de dos (2^cost, normalmente entre 10 y 12). Subirlo en uno duplica aproximadamente el tiempo de cada hash — y duplica el coste total de un ataque de fuerza bruta. Esto permite subir el cost factor con los años sin cambiar de algoritmo.

Sal integrada

Bcrypt genera automáticamente una sal aleatoria única para cada contraseña y la incorpora directamente en el resultado — no hay nada que guardar por separado. Dos contraseñas idénticas producen hashes distintos, y las rainbow tables precalculadas para contraseñas comunes dejan de servir: hay que atacar cada hash individualmente.

Para qué se necesita esto

  • Almacenar correctamente las contraseñas de los usuarios en la base de datos de una aplicación.
  • Entender por qué SHA-256 o MD5 son una mala elección para hashear contraseñas.
  • Probar o migrar un sistema de autenticación que use bcrypt, incluyendo la compatibilidad entre prefijos $2a$/$2b$/$2y$.

El límite oculto: 72 bytes

Bcrypt solo procesa los primeros 72 bytes de la contraseña — el resto se descarta silenciosamente, sin aviso. En la práctica esto rara vez es un problema para contraseñas en español (72 caracteres ASCII ya es muchísimo), pero conviene tenerlo en cuenta al validar la longitud máxima permitida en un formulario de registro, sobre todo si se aceptan frases de contraseña largas.

Probar la herramienta