Bcrypt
Genera un hash bcrypt o comprueba una contraseña contra uno sin salir del navegador: elige el coste y la variante $2a$, $2b$ o $2y$, y desmonta cualquier hash.
Nada de lo que escribas aquí sale de este navegador. El trabajo corre en un Web Worker de esta pestaña: abre tu propio panel de red y míralo, no sale ni una petición mientras calcula.
Generar un hash
Una contraseña, un coste y una variante. La sal se toma nueva de este navegador en cada ejecución, así que la misma contraseña da un hash distinto cada vez: así funciona bcrypt, no es un fallo.
Comprobar una contraseña contra un hash
Un hash pegado se desmonta al instante, sin contraseña y sin esperas. Añade la contraseña para saber si coincide. Un hash no se puede invertir, ni aquí ni en ningún sitio.
Qué hay realmente dentro de un hash de bcrypt
Un hash de bcrypt es una única cadena de sesenta caracteres, y cada una de sus partes está a la vista. Nada en ella es secreto salvo la contraseña que la produjo, y esa no está ahí en absoluto. Desmontarla no exige clave, ni contraseña, ni cálculo alguno: esta página lo hace en el momento en que pegas una.
- La variante, el campo con el que abre la cadena: $2b$, $2a$ o $2y$. Dice según las reglas de quién se produjo el hash.
- El coste, escrito con exactamente dos cifras: de 04 a 31. Es un exponente, así que un coste de 12 significa 2^12 — 4.096 — rondas de estiramiento de clave, y el coste 13 es el doble de trabajo que el 12 y no una treceava parte más.
- La sal, veintidós caracteres: dieciséis bytes aleatorios, guardados a la vista junto a la respuesta que salaron.
- El digest, los últimos treinta y un caracteres: veintitrés bytes de salida. Es la única parte que depende de la contraseña, y no es el hash — el hash es la cadena entera.
El alfabeto del que salen esos caracteres es el propio de bcrypt, y no es Base64 estándar: va ./A-Za-z0-9, así que un punto y una barra lo abren donde Base64 pone el más y la barra al final. Decodificarlo con un decodificador Base64 corriente devuelve bytes equivocados en vez de un error, y esa es una manera clásica de perder una tarde.
El límite de setenta y dos bytes se cuenta en bytes, y eso importa
bcrypt lee como mucho setenta y dos bytes de una contraseña y no hace caso de nada que venga después. No setenta y dos caracteres — setenta y dos bytes de UTF-8, así que cuántos caracteres son depende de lo que cuesten las letras de cada idioma: las veintiséis letras latinas sin signo cuestan un byte cada una, y cualquier otra letra cuesta más. En español la diferencia es pequeña y real a la vez: cada vocal acentuada, la ü y la ñ cuestan dos bytes, así que una contraseña con unos cuantos acentos llega al límite algunos caracteres antes de los setenta y dos. Una hecha solo de esas letras lo alcanzaría en treinta y seis.
- ASCII cuesta un byte por carácter, así que quien habla inglés llega al límite en setenta y dos caracteres y casi nunca lo hace.
- El hebreo, el árabe, el ruso y el griego cuestan dos bytes por letra, así que el límite llega a los treinta y seis caracteres.
- El japonés, el coreano y el chino cuestan tres, así que llega a los veinticuatro.
- La mayoría de los emoji cuestan cuatro, y muchos de los que la gente escribe de verdad son varios puntos de código unidos entre sí, así que un puñado ya es todo el presupuesto.
El contador de bytes bajo el campo de la contraseña está ahí para que esto sea algo que puedas ver acercarse en vez de descubrirlo después. Y el corte cae en el byte, no en el carácter, exactamente como lo hace cualquier implementación de referencia — así que un carácter multibyte que quede sobre la frontera pierde una parte de sí y conserva el resto. Ese es el comportamiento compatible y no un defecto, y esta página lo dice cuando ocurre.
Y ahora la parte que explica todo lo demás: el recorte es invisible en la respuesta. La expansión de la clave mezcla exactamente setenta y dos bytes de clave en su estado y nunca da la vuelta con una más larga, así que hashear una contraseña de cien bytes y hashear sus primeros setenta y dos bytes producen el mismo digest. No hay nada que una implementación pueda detectar ni nada que pueda informar, y por eso ninguna biblioteca lanza un error y por eso dos contraseñas largas distintas que coincidan en sus primeros setenta y dos bytes encajan las dos con el mismo hash guardado. Esta página tampoco puede rechazar una contraseña larga — si la estás comprobando contra un hash que un sistema real produjo recortando, necesitas la respuesta — así que te da la respuesta y te dice qué se cortó.
La variante cambia el prefijo y no el digest
La variante parece un número de versión y no lo es. Las tres que escribe esta herramienta no están ordenadas, ninguna sustituye a otra, y elegir entre ellas es una decisión de compatibilidad y no de seguridad.
- $2b$ es aquella en la que se asentó OpenBSD y la que emiten hoy Python, Node y Go. Es el valor por defecto aquí y la respuesta correcta cuando nada obliga a otra cosa.
- $2a$ es la más antigua, y algunos despliegues veteranos de Java y Spring Security siguen esperando verla.
- $2y$ es la que escribe password_hash de PHP y, por tanto, Laravel, así que un hash que se pega a ese mundo suele quererla.
Lo que separa a las tres es cómo tratan una clave de más de 255 bytes, y bcrypt ya ha dejado de leer en los setenta y dos — así que ninguna contraseña que puedas escribir aquí llega a esa diferencia. Para todo lo que esta herramienta vaya a recibir alguna vez, las tres producen los mismos veintitrés bytes y solo se separan en los cuatro caracteres del principio. Cambia la variante y el digest no se mueve.
Existen otras dos y esta herramienta las nombra en lugar de calcularlas. $2x$ no es un arreglo: Openwall la acuñó para reproducir a propósito un error de extensión de signo, de modo que los hashes hechos por el código roto se pudieran seguir comprobando, e implementarla aquí sería meter un defecto conocido dentro de la propia herramienta. $2$ es la original, de antes de que se añadiera a la clave el byte cero final. Ninguna de las dos la emite nada actual; si tienes una entre manos, salió de un sistema tan viejo que la variante es lo de menos de cuanto has encontrado.
El coste, y lo que cuesta en tu propia máquina
El coste es el factor de trabajo, de 4 a 31, y es un exponente: cada paso duplica el tiempo. En eso consiste bcrypt entero. Un hash de contraseña debe ser lento, porque un atacante que tiene una tabla robada paga el mismo precio en cada intento, y duplicar el coste reduce a la mitad el número de intentos por segundo que consigue por su dinero.
Lo que tarda de verdad un coste dado es un hecho sobre la máquina que lo ejecuta, no un número que se pueda escribir de antemano: un teléfono y un servidor están a dos órdenes de magnitud de distancia. Por eso esta página mide en vez de citar: ejecuta un hash corto en tu propio dispositivo al cargar y extrapola desde ahí, y por eso la estimación junto al control del coste está vacía un instante y luego aparece. Por encima de unos pocos segundos pregunta antes de empezar, para que una cifra mal tecleada no se lea como una página colgada.
Para elegir un número: 12 es lo que emiten por defecto Laravel y el paquete bcrypt de Python, y hoy es un mínimo razonable en producción. Los costes más bajos son para fixtures de prueba, donde un conjunto de pruebas que siembra cincuenta usuarios no debería gastar un segundo por usuario. Los costes por encima de 15 conviene medirlos contra tu tráfico real de inicios de sesión antes de publicarlos, porque cada inicio de sesión paga también el precio.
# Apache: escribir una línea de htpasswd con coste 12
htpasswd -nbBC 12 alice "correct horse battery staple"
# PHP y Laravel: password_hash emite $2y$
php -r 'echo password_hash("correct horse battery staple", PASSWORD_BCRYPT);'
# Python: el paquete bcrypt emite $2b$, y gensalt toma el coste
python -c "import bcrypt; print(bcrypt.hashpw(b'correct horse battery staple', bcrypt.gensalt(12)))"La sal, y cuándo un hash hecho aquí no es para guardar
La sal son dieciséis bytes aleatorios sacados de nuevo para cada hash, y se guarda a la vista dentro de la propia cadena. No es un secreto ni se pensó nunca como tal: su trabajo es que dos contraseñas idénticas produzcan dos hashes sin relación entre sí, de modo que una tabla robada no se pueda atacar con un único diccionario precalculado.
Por eso también la misma contraseña te da aquí un hash distinto cada vez que pulsas el botón. No es un fallo y la respuesta anterior no está caduca: una sal nueva es bcrypt funcionando. Cualquiera de esos hashes coincide con la contraseña, porque la sal viaja dentro de la cadena que se comprueba.
El campo avanzado de la sal existe para una sola tarea: reproducir exactamente el hash de otra persona, para poder comparar dos implementaciones. Pega un hash entero en él y el coste y la variante lo siguen automáticamente, así que la contraseña correcta reproduce la entrada carácter a carácter. Todo lo que produzcas de ese modo es para comparar y no para guardar: una sal usada dos veces es una sal que ha dejado de hacer su trabajo.
Un hash de bcrypt no se puede invertir
La gente llega a páginas como esta buscando la manera de descifrar un hash de bcrypt. No la hay, y la razón no es que sea difícil: la contraseña no está en la cadena. Sesenta caracteres llevan una variante, un coste, dieciséis bytes aleatorios y veintitrés bytes de salida, y ninguna combinación de todo eso contiene una contraseña de longitud alguna. Nada se cifró, así que no hay nada que descifrar.
Lo que un sitio sí puede hacer — y lo que hacen los que anuncian descifrado — es adivinar. Se toma una lista de contraseñas comunes, se hashea cada una contra tu sal y con tu coste, y se mira si alguna coincide. bcrypt está diseñado para hacer caro justamente eso, que es para lo que sirve el coste, y esta herramienta no lo ofrece de ninguna forma.
La versión honesta de esa pregunta suele ser otra, y esa sí tiene respuesta: ¿qué hay en esta cadena, y la produce esta contraseña en concreto? Las dos están en esta página. Pega el hash para ver todo lo que lleva, y añade una contraseña para obtener un sí o un no.
Preguntas frecuentes
- ¿Se envía mi contraseña a un servidor?
- No. Todo ocurre en esta pestaña del navegador: el hasheo corre en un Web Worker de tu propia máquina, la contraseña nunca entra en la URL y no se escribe nada en el almacenamiento del navegador. Abre tu panel de red, escribe una contraseña y pulsa el botón: no sale ni una petición. Esa es la diferencia entre esta página y los dos sitios que la superan en los resultados para la misma pregunta.
- ¿Se puede descifrar un hash de bcrypt y recuperar la contraseña?
- No, y no porque sea difícil. La contraseña no está en la cadena: lo que hay es una variante, un coste, una sal y veintitrés bytes de salida, y nada de eso contiene la entrada. Cualquiera que ofrezca descifrar uno está adivinando contraseñas comunes contra tu sal, que es precisamente lo que bcrypt está diseñado para hacer lento.
- ¿Por qué la misma contraseña da un hash distinto cada vez?
- Porque en cada ejecución se toma una sal aleatoria nueva, y la sal es parte de la cadena. Todos esos hashes coinciden con la misma contraseña — el comprobador lee la sal del hash que pegas, así que no necesita saber qué ejecución lo produjo.
- Mi contraseña se cortó a los setenta y dos bytes. ¿Por qué no hubo error?
- Porque no hay nada que detectar. bcrypt mezcla exactamente setenta y dos bytes de clave en su estado y nunca lee más allá, así que una contraseña larga y sus primeros setenta y dos bytes producen el mismo digest: el recorte no deja rastro que una biblioteca pueda advertir. Esta página te dice que ocurrió, que es lo máximo que una implementación puede hacer honestamente.
- ¿Por qué mi contraseña llegó al límite a los treinta y seis caracteres?
- Porque el límite son setenta y dos bytes y no setenta y dos caracteres, y las letras del hebreo, el árabe, el ruso y el griego cuestan dos bytes cada una en UTF-8. Las del japonés, el coreano y el chino cuestan tres, así que allí el límite llega a los veinticuatro caracteres, y la mayoría de los emoji cuestan cuatro. En español pasa lo mismo con cada vocal acentuada y con la ü y la ñ: una contraseña hecha solo de ellas se corta a los treinta y seis. El contador bajo el campo muestra los bytes según escribes.
- ¿Qué variante debo elegir?
- La que espere el sistema en el que vas a pegarla: $2y$ para PHP y Laravel, $2a$ para Spring Security antiguo, $2b$ en todo lo demás. Es una decisión de compatibilidad y no de seguridad: con cualquier longitud que se le pueda dar a esta herramienta, las tres producen digests idénticos y solo se separan en esos cuatro caracteres del principio.
- ¿Qué coste debo usar?
- 12 es el valor por defecto habitual y un mínimo razonable en producción. Usa un coste bajo para fixtures de prueba, para que tu conjunto de pruebas no pague cincuenta veces el estiramiento de clave, y mide primero cualquier cosa por encima de 15 contra tu tráfico real de inicios de sesión, porque cada inicio de sesión correcto paga el mismo precio que un atacante.
- ¿Es seguro poner en una tabla real de usuarios un hash hecho aquí?
- Para sembrar una base de datos, escribir un fixture o añadir una línea de htpasswd, sí: la sal viene de la fuente criptográfica de aleatoriedad de tu navegador. Pero esto es una página de borrador y no un servicio de credenciales: si escribes tú la sal, el resultado deja de ser seguro para guardar, cosa que la página dice en ese momento, y una contraseña que merezca protegerse se acuña mejor allí donde va a vivir.
- ¿Por qué mi hash empieza por $2y$ si el código que lo hizo dice bcrypt?
- Porque password_hash de PHP escribe $2y$, y Laravel está construido sobre él. Es el mismo algoritmo que $2b$; la variante registra qué implementación escribió la cadena. Un comprobador que la rechace está rechazando la variante, no fallando al comparar la contraseña.
- Pegué un hash y dice que la sal está escrita de otro modo. ¿Está roto?
- No. Veintidós caracteres pueden codificar más bits de los que necesitan dieciséis bytes, así que se descartan cuatro bits del final y algunas sales tienen más de una escritura que decodifica a los mismos bytes. Sistemas reales las han emitido, así que esta página lee un hash así en vez de rechazarlo, y te dice cuál es la escritura canónica.
Herramientas relacionadas
- Decodificador / verificador de JWT
Decodifica y verifica JSON Web Tokens: firma y claims.
- Generador de hash
MD5, SHA-1, SHA-256, SHA-384 y SHA-512 a la vez.
- Decodificador de certificados y PEM
Lee un certificado X.509 o una CSR sin OpenSSL.
- Generador de HMAC
Firma un mensaje con una clave o verifica la firma de un webhook.