¿Necesitas un hash bcrypt para meter a mano un usuario de prueba en tu base de datos, o quieres comprobar si una contraseña corresponde al hash que tienes guardado? Este generador bcrypt online hace las dos cosas en tu navegador: genera el hash con el coste que elijas (de 4 a 14) y verifica una contraseña contra un hash existente. Viene bien con Laravel, que tanto se usa en España y Latinoamérica, o con Spring Security, que usan bcrypt por defecto. Y cuenta con algo que muchos olvidan: la «ñ» y las tildes ocupan dos bytes en UTF-8, y bcrypt solo lee los primeros 72 bytes.
Qué es bcrypt, en un párrafo
Bcrypt es un algoritmo de hash para contraseñas: una función que recibe una contraseña en texto plano y devuelve una cadena de longitud fija que guardas en lugar de la contraseña. Dos cualidades lo hacen útil precisamente para contraseñas: es lento a propósito (tú decides cuánto con el factor de coste) e incluye una sal aleatoria, así que dos usuarios con la misma contraseña obtienen hashes distintos. Lento y con sal significa que romper por fuerza bruta unos hashes filtrados pasa de «minutos» con MD5 o SHA-1 a «siglos» con bcrypt.
Se publicó en 1999, lleva más de una década como hash de contraseñas por defecto en Rails, Spring Security, Laravel y muchos otros frameworks (Django lo ofrece como opción) y OWASP lo sigue considerando aceptable hoy. El generador bcrypt calcula el hash de un texto plano (con el coste que elijas) y verifica un texto plano contra un hash existente.
Cómo funciona el generador bcrypt de Microapp
Elige el modo (generar el hash de una contraseña o verificar un hash). En el modo de generar: escribe el texto plano, mueve el factor de coste (de 4 a 14) y pulsa el botón para generar. En el modo de verificar: pega un hash existente y el texto plano que quieres comprobar, y pulsa Verificar. El resultado es Coincide (✓) o No coincide (✗).
Las dos operaciones se hacen por completo en tu navegador con la librería bcryptjs. Ni tu contraseña en texto plano ni el hash salen de tu equipo: no hay viaje al servidor, ni registros, ni analíticas sobre lo que pegas. La Web Crypto API no trae bcrypt de serie (tiene SHA, HMAC, AES), así que usamos la implementación en JavaScript.
hello con coste 10. Un resultado posible: $2b$10$dSPJFNaVX1ulSQipa1Mat.iYA2o3KVgpQrPP7.YFY3qypKSvWx2LW. Si vuelves a generar el hash con la misma entrada, sale un resultado distinto cada vez (por la sal aleatoria), pero bcrypt.compare("hello", <cualquiera de esos hashes>) devuelve true en todos los casos. La sal va dentro del propio hash: no hace falta una columna aparte.
Qué hace realmente el factor de coste
El coste de bcrypt (el número entre el segundo y el tercer $ del hash) controla el número de rondas internas: 2coste. Coste 10 = 1024 rondas. Coste 11 = 2048. Coste 12 = 4096. Cada paso duplica el trabajo. La idea es ajustar el tiempo por hash a unos 100–300 ms en tu servidor de autenticación: lo bastante lento para que romper hashes filtrados no sea práctico, y lo bastante rápido para que un inicio de sesión legítimo siga pareciendo instantáneo.
| Coste | Rondas | Tiempo aprox. en un servidor moderno | Uso |
|---|---|---|---|
| 4 | 16 | ~1 ms | Solo pruebas y fixtures, nunca en producción |
| 10 | 1024 | ~100 ms | Mínimo de OWASP para producción |
| 12 | 4096 | ~400 ms | Bancos, gestores de contraseñas, apps de alta seguridad |
| 14 | 16 384 | ~1,5 segundos | Rendimiento decreciente; los usuarios notan la espera |
Recomendación actual: coste 10–12 en producción. Por encima de 12 empiezas a añadir una espera que se nota al iniciar sesión; por debajo de 10 te arriesgas a quedarte atrás frente al hardware nuevo. Vuelve a ajustarlo cada 2 o 3 años, a medida que las máquinas son más rápidas.
Por qué bcrypt añade la sal solo
Cada llamada a bcrypt.hash() genera una sal aleatoria nueva de 16 bytes y la mete en el hash resultante. El formato es $2b$10$<sal><hash>: los primeros 22 caracteres en base64 después del coste son la sal, y el resto es el hash. Para verificar, bcrypt saca la sal del hash guardado y vuelve a calcular el hash de la contraseña candidata con ella: si el resultado coincide, las contraseñas son la misma.
Por qué importa: sin sal, dos usuarios con la misma contraseña producen el mismo hash. Los atacantes precalculan «tablas arcoíris» que asocian contraseñas comunes con sus hashes; una sola búsqueda rompe a la vez a todos los usuarios con «password123». Con una sal por usuario, cada hash es único aunque las contraseñas sean idénticas, lo que inutiliza las tablas arcoíris y obliga al atacante a atacar cada hash por separado.
¿Qué son $2a, $2b y $2y?
Son variantes casi idénticas de bcrypt, y para verificar son compatibles entre sí. $2a es la versión de referencia que se extendió a finales de los noventa. $2y es la marca que introdujo PHP en 2011, cuando corrigió un fallo de su implementación con caracteres de 8 bits (como la «ñ» o las vocales con tilde). $2b es la corrección de OpenBSD de 2014 para contraseñas de más de 255 bytes. bcrypt.compare verifica las tres sin importar cuál generó el hash. Este generador produce hashes $2b; muchas librerías aún generan $2a, y las bases de datos antiguas de PHP suelen tener $2y.
¿Debería usar Argon2?
Argon2id ganó la Password Hashing Competition en 2015 y es la primera recomendación de OWASP para sistemas nuevos. Exige mucha memoria (lo que lo hace lento en GPU), se ajusta mejor (controlas por separado el tiempo, la memoria y el paralelismo) y no se diseñó en 1999. Los sistemas nuevos deberían usarlo si su stack lo permite.
Bcrypt sigue siendo aceptable en todas partes y es lo que usa la mayoría de los sistemas existentes: no hay prisa por migrar un despliegue de bcrypt que funciona. Para sistemas nuevos: Argon2id si tu librería lo soporta (Node tiene argon2, Python argon2-cffi, Rust argon2); bcrypt si dependes de herramientas más antiguas o tu equipo lo conoce mejor.
Errores frecuentes
Guardar la sal por separado. No lo hagas. La sal forma parte del hash: guarda la cadena completa de 60 caracteres en una sola columna. Separarla en varias columnas añade errores y cero seguridad.
Mantener el mismo coste durante décadas. Si tu código sigue usando coste 8 desde 2010, estás poco protegido frente al hardware actual. Súbelo a 10–12 y vuelve a calcular el hash de cada usuario en su próximo inicio de sesión.
Olvidar el límite de 72 bytes. Bcrypt solo usa los primeros 72 bytes de la entrada; el resto se ignora sin avisar. Son bytes, no caracteres: en UTF-8, la «ñ» y las vocales con tilde ocupan dos. Si quieres admitir contraseñas más largas y pasas la contraseña antes por SHA-256, codifica el resultado en hex o base64: el resumen binario en bruto puede contener bytes nulos que algunas implementaciones toman como fin de cadena.
Comparar hashes con === en JavaScript. Usa siempre bcrypt.compare() para verificar: extrae la sal y compara en tiempo constante. La comparación directa de cadenas está mal por varios motivos, empezando por que dos hashes de la misma contraseña nunca son iguales.
Herramientas relacionadas
Para hashes de un solo sentido pensados para comprobar integridad (sumas de verificación de archivos, direccionamiento por contenido), usa el Generador SHA-256 o el Generador de hash MD5. Para crear contraseñas aleatorias fuertes que luego pasarás por bcrypt, mira el Generador de contraseñas. Para tokens aleatorios (distintos de las contraseñas: al tener tanta entropía, basta con un hash rápido como SHA-256 antes de guardarlos, sin necesidad de bcrypt), el Generador de tokens es lo indicado. Para códigos de autenticación en dos pasos, mira el Generador de OTP.