/ Investigación · Seguridad web · Noviembre 2026
¿Cuánto tardaría en robar tu contraseña?
Cuando a una web le roban la base de datos, ¿qué decide si tu contraseña se rompe en segundos o no se rompe nunca? Guardé las mismas 20 contraseñas de las cuatro formas que usan las webs y las ataqué desde un portátil. El resultado depende de la contraseña y de cómo la guarda la web, y lo segundo no lo elige quien se registra.
Esto es con la base de datos ya robada. El atacante tiene los hashes en su equipo y prueba sin límite. En un login normal la web puede frenar los intentos, y es otro escenario: aquí no digo que alguien adivine tu Instagram desde la pantalla de inicio de sesión. Tampoco están aquí los comandos exactos ni los hashes.
/ En resumen
Los números
/ 01 · Al registrarte
Qué le pasa a tu contraseña cuando te registras
Una web bien hecha no guarda tu contraseña. Guarda un hash: el resultado de pasarla por una fórmula de la que no se puede volver atrás. Son cinco pasos.
- 1
Escribes la contraseña
En el formulario. Viaja al servidor cifrada por HTTPS.
- 2
El servidor genera una sal
Un valor aleatorio, distinto para cada usuario.
- 3
La pasa por la fórmula
Contraseña y sal, con el coste que eligió quien hizo la web. En este paso se fija cuánto cuesta cada intento.
- 4
Guarda una sola línea
Algoritmo, coste, sal y hash juntos. bcrypt con coste 12 empieza por
$2y$12$; Argon2id lleva escrita su configuración:$argon2id$v=19$m=47104,t=1,p=1$. - 5
Olvida la contraseña
Cuando vuelves, repite la cuenta con la sal guardada y compara. Si sale lo mismo, entras.
Si alguien roba la base de datos, se lleva esas líneas. No ve tu contraseña: tiene que adivinarla, calcular el hash de cada intento y compararlo. Cuánto le cuesta cada intento lo decidió la web en el paso 3.
Otro escenario
Login normal
- El atacante prueba en el formulario de la web, de uno en uno.
- La web puede frenarle: límite de intentos, bloqueo temporal, segundo factor.
- Lo que decide: esas defensas y que tu contraseña no sea de las más comunes.
Lo que mide este test
Base de datos robada
- El atacante tiene los hashes en su equipo y prueba sin pedir permiso.
- No hay límite de intentos y el segundo factor no sirve.
- Lo que decide: cómo se guardó la contraseña y cómo de previsible es.
/ 02 · Las cuatro formas
Qué es cada forma de guardar una contraseña
Las cuatro formas del test calculan un hash, pero se diseñaron para cosas distintas.
| Forma | Qué es | Para qué se diseñó | ¿Sirve para contraseñas? |
|---|---|---|---|
| MD5 | Un resumen de 128 bits, de 1992. Muy rápido de calcular. | Comprobar que un archivo no ha cambiado, como una huella. Hoy está roto incluso para eso. | No. Es rápido a propósito. |
| SHA-256 | Un resumen de 256 bits, de la familia SHA-2 (2001). Rápido y seguro como huella. | Firmas digitales, certificados TLS, integridad de archivos. | Solo, no. También es rápido a propósito. |
| bcrypt | Una fórmula de 1999 hecha para contraseñas. Lleva sal y un coste: cada punto de coste duplica el trabajo. Coste 12 son 4.096 repeticiones. | Guardar contraseñas. | Sí. OWASP pide coste 10 como mínimo. |
| Argon2id | La fórmula que ganó el concurso de hashes de contraseñas de 2015. Lleva sal y, además de tiempo, exige memoria en cada intento. | Guardar contraseñas, también contra tarjetas gráficas. | Sí. Es la primera opción de OWASP. |
La sal hace que dos personas con la misma contraseña tengan hashes distintos, así que el atacante no puede atacarlas a la vez. En el test, MD5 y SHA-256 iban sin sal, como en muchas webs antiguas.
/ 03 · Velocidad
El mismo ataque, a cuatro velocidades
Cuántos intentos por segundo puede hacer el atacante depende solo de la forma que eligió la web. Estas son las velocidades máximas medidas en el mismo portátil.
| Cómo la guarda la web | Intentos por segundo | Más lento que MD5 | Lo que MD5 prueba en 1 s |
|---|---|---|---|
| MD5 | 11.351.300.000 | Referencia | 1 s |
| SHA-256 | 2.878.100.000 | 3,9 veces | 3,9 s |
| Argon2id | 2.478 | 4,6 millones de veces | 53 días |
| bcrypt | 317 | 35,8 millones de veces | 414 días |
Lo que MD5 prueba en 1 segundo
bcrypt tarda 414 días en probar lo mismo. Cada cuadrado gris es un día.
Por qué salen estas velocidades
- MD5 y SHA-256 son cuentas cortas. Una tarjeta gráfica tiene miles de núcleos pequeños que hacen la misma operación a la vez, y estas fórmulas casi no usan memoria. Por eso la RTX 4060 hace miles de millones por segundo. SHA-256 va unas 3,9 veces más lento porque su cuenta es más larga.
- bcrypt es caro a propósito. Con coste 12 repite su preparación 4.096 veces y, durante todo el cálculo, lee y escribe sin parar en una tabla de 4 KB. Las tarjetas gráficas llevan mal ese tipo de acceso a memoria: muchos de sus núcleos se quedan esperando.
- Argon2id pide memoria. Cada intento necesita 46 MiB. La RTX 4060 del portátil tiene 8 GB, así que caben como mucho unos 170 intentos a la vez (cálculo). Pero con una sola pasada, cada intento recorre esa memoria una vez, y mover memoria es justo lo que una tarjeta gráfica hace rápido.
Velocidades medidas durante el ataque, no en el benchmark de la herramienta. En MD5 y SHA-256 la máxima sale de la fase de fuerza bruta: en la de diccionario el límite era leer la lista del disco, unos 500 millones de intentos por segundo. En bcrypt y Argon2id el límite es el propio hash en todas las fases. Un equipo con más o mejores tarjetas iría más rápido; este test no mide cuánto.
/ 04 · El ataque
Con qué se atacó: una lista filtrada, combinaciones y fuerza bruta
Un atacante no prueba al azar. Empieza por contraseñas que la gente ya ha usado y deja para el final lo de probar carácter a carácter. El test hizo lo mismo, en este orden y con las mismas piezas contra las cuatro formas:
- Fase 1: diccionario
rockyou
14.344.391 contraseñas de usuarios de una filtración de 2009, públicas desde entonces. La base de casi cualquier ataque.
- Fase 1: diccionario
Reglas best66
Las variaciones de siempre sobre cada palabra de rockyou: mayúscula inicial, letras por números, sufijos.
- Fase 2: combinaciones
354 piezas propias
Nombres de One Piece, palabras inglesas comunes, los años de 1990 a 2026 y sufijos como
!,123,@o404. - Fase 2: combinaciones
princeprocessor
Junta esas piezas de dos en dos y de tres en tres. Es lo que montó CrazyCatLady.
- Fase 3: fuerza bruta
Máscara
Carácter a carácter, unos 20 minutos. Solo contra MD5 y SHA-256: bcrypt, a 317 por segundo, no cubriría ni las de 4 caracteres (cálculo).
Ninguna de las 20 contraseñas estaba en la lista de 354 piezas, comprobado por código. Las comunes sí podían estar en rockyou de forma natural, y eso era justo lo que quería medir. CrazyCatLady no estaba en ninguna lista: el programa la montó juntando crazy, cat y lady.
/ 05 · Las 20
Las 20 contraseñas, por grupos
Ninguna es de nadie: las elegí a mano para probar una idea por grupo. En rojo, las que cayeron. Las mismas 20 se guardaron de las cuatro formas.
| Grupo | Por qué | Las contraseñas | Cayeron con MD5 y SHA-256 |
|---|---|---|---|
| Comunes | Esperaba que cayeran al instante. | ineedapasswordiforgotPleaseUseMe | 2 / 3 |
| Parecen fuertes | Mayúsculas, símbolos y números con patrón. | ZoroGotLostAg@in!404SuuuuperRRRrr!77SniperKing=Usopp?100% | 0 / 3 |
| Bromas de internet | No sabía de qué lado caerían. | FBISurveillanceVanCrazyCatLadyEarlyAlzheimersPorqueFi | 1 / 4 |
| Frases de palabras | Esperaba que aguantaran por largas. | memorysuckswhydoialwaysforgetNoOneHasntDoneXGopuLongHairedFreakyPeopleNeedNotApplyDiarrheaIsHereditary.ItRunsN1sJeans. | 0 / 5 |
| La ridícula larga | 68 caracteres. | IndianMilitaryCyberIntelligenceWing | 0 / 1 |
| Aleatorias | De un generador criptográfico: 8, 12, 16 y 20 caracteres. | nGA295h{xsor{lR=^yu=jR4(QY5GWgTS^Bm7j%=bQHxw{NTC0GE^^y1= | 0 / 4 |
/ 06 · Qué cayó
Qué cayó y por qué
Con MD5 y con SHA-256 cayeron las mismas tres. Con bcrypt y Argon2id, ninguna, ni las que estaban en rockyou.
| Contraseña | Cómo cayó | MD5, como mucho | SHA-256, como mucho | bcrypt y Argon2id |
|---|---|---|---|---|
| ineedapassword | Estaba tal cual en rockyou, una lista de 14,3 millones de contraseñas filtradas que es pública. | 7,2 s | 24,1 s | No cayó |
| iforgot | También en rockyou. | 7,2 s | 24,1 s | No cayó |
| CrazyCatLady | No estaba en rockyou. La montó un programa combinando palabras comunes de una lista: crazy, cat y lady. | 27,6 s | 45,1 s | No cayó |
Cada tiempo es el final de la fase en la que cayó la contraseña, contado desde que empieza el ataque: cayó en ese tiempo o antes. Con bcrypt y Argon2id ni siquiera se terminó de recorrer el diccionario en los 10 minutos de cada fase: a 317 intentos por segundo, recorrer rockyou con sus variaciones llevaría hasta unos 35 días; a 2.478, unos 4.
Tres cosas que no esperaba
- ZoroGotLostAg@in!404 aguantó, también con MD5. Tiene mayúsculas, símbolos y números. En cambio CrazyCatLady, sin símbolos, cayó porque son tres palabras comunes.
- PleaseUseMe parecía común y no cayó. No estaba en rockyou y las variaciones del diccionario no llegaron a ella.
- PorqueFi no cayó, pero no es segura. Tiene 8 caracteres, solo letras. La fuerza bruta del test llegó a 6 o 7 caracteres; probando solo letras, MD5 la sacaría en unas 1,3 horas (cálculo).
/ 07 · La configuración
Manda la configuración del algoritmo
Decir «esta web usa bcrypt» o «usa MD5» no basta. Lo que fija el precio de cada intento son los parámetros con los que se usa: el coste, la memoria, las pasadas, la sal.
Argon2id, más moderno, aguantó menos que bcrypt
Con los parámetros del test, bcrypt aguantó unas 8 veces más: 317 intentos por segundo, frente a 2.478 de Argon2id. Argon2id iba en el mínimo que recomienda OWASP (46 MiB y una pasada, la primera opción de su lista). bcrypt iba por encima del suyo: coste 12, cuando el mínimo es 10. Argon2id con más memoria o más pasadas sería más lento de atacar, y bcrypt con coste 10, unas 4 veces más rápido (cálculo: cada punto de coste duplica el trabajo). Subir los parámetros tiene un precio: el servidor tarda más en cada inicio de sesión.
No todo «MD5» es el MD5 del test
WordPress usó hasta la versión 6.7 un sistema llamado phpass. Por dentro es MD5, pero con sal y repetido 8.192 veces. La etiqueta es la misma, pero deja unas 8.000 veces menos intentos por segundo. Aun así es miles de veces más rápido de atacar que bcrypt con coste 12.
Un límite de bcrypt: solo usa los primeros 72 bytes de la contraseña. La de 68 caracteres del test cabe por poco. Por eso WordPress 6.8 resume antes la contraseña con SHA-384 y pasa ese resumen a bcrypt.
/ 08 · En los CMS
Cómo guardan las contraseñas WordPress, Drupal y compañía
La mayoría de las webs no programan esto: lo hereda el gestor de contenidos. Así ha ido cambiando en los más usados.
| CMS | Antes | Ahora | Ojo con |
|---|---|---|---|
| WordPress | phpass (MD5 con sal, repetido), prefijo $P$, hasta la 6.7. | Desde la 6.8 (abril 2025), bcrypt tras resumir con SHA-384, prefijo $wp$2y$. Argon2id, opcional. | Los hashes viejos se rehacen al volver a entrar. Quien no vuelve sigue en $P$. |
| Drupal | MD5; desde Drupal 7, phpass con SHA-512 ($S$). | bcrypt desde Drupal 10. Argon2id está anunciado a partir de Drupal 12. | Argon2id es un cambio anunciado para Drupal 12: comprueba tu versión. |
| Joomla | MD5 con sal. | bcrypt desde Joomla 3.2 (2013). | Sitios sin actualizar en años. |
| Magento | Magento 1: MD5 con sal. | Argon2id si el servidor tiene la extensión Sodium (PHP 7.3 o superior). | Sin Sodium cae a SHA-256 con sal por cliente: un hash rápido. |
| PrestaShop | md5(_COOKIE_KEY_ . contraseña): una sola clave para toda la tienda. | En la 1.7 guarda las nuevas con bcrypt, pero sigue aceptando el MD5 antiguo. | Cuál usa una tienda concreta solo se sabe mirándola. |
Cómo saber qué usa tu web: mira la columna de la contraseña de un usuario en la base de datos. Los primeros caracteres indican el formato.
$P$- phpass, WordPress antiguo
$wp$2y$- WordPress 6.8 o posterior, bcrypt
$2y$o$2b$- bcrypt; el número siguiente es el coste
$argon2id$- Argon2id, con la memoria (
m) y las pasadas (t) escritas $S$- Drupal 7
- 32 / 64 hex
- Nada más que hexadecimal: MD5 o, con 64, probablemente SHA-256
En mi propia web, devilfruittcg.com, con WordPress: lo comprobé y guarda las contraseñas con bcrypt.
El hash solo entra en juego cuando ya han robado la base de datos. Antes hay otras defensas: actualizar el CMS y los plugins, que es por donde suelen robar las bases de datos; limitar los intentos de login, que WordPress no hace de serie (se añade con un plugin o en el proxy), y el segundo factor para las cuentas de administración.
/ 09 · El caso LastPass
El mismo problema, en un gestor de contraseñas
En 2022 robaron a LastPass copias de seguridad de las cajas fuertes de sus usuarios. No era una web con una tabla de hashes, pero el fallo es el mismo que mide este test: cuánto trabajo cuesta cada intento.
- La llave de cada caja sale de la contraseña maestra con PBKDF2, que va repitiendo un hash rápido de la familia SHA. Las repeticiones, que LastPass llama iteraciones, hacen de coste.
- El valor por defecto subió, pero las cuentas antiguas no se actualizaron solas. Había cuentas en 5.000, en 500 e incluso en 1.
- Las direcciones de las webs guardadas iban sin cifrar. Las contraseñas y notas, sí. El atacante podía ver a qué sitios pertenecía cada entrada y elegir qué cajas atacar primero.
- LastPass habló de «millones de años» para romper una maestra. El analista Wladimir Palant respondió que eso confunde la fuerza bruta pura con una contraseña que elige una persona: con una sola tarjeta gráfica, una maestra de 40 bits de entropía caería en unos dos meses, según sus cálculos.
Las iteraciones por defecto de LastPass
- Al principio
1 iteración
- Junio 2012
500
- Febrero 2013
5.000
- Febrero 2018
100.100sin migrar las cuentas viejas
- OWASP, 2022
310.000 recomendadas
La diferencia con este test: aquí se compara bcrypt con MD5 en una web; en LastPass fue PBKDF2 con pocas repeticiones en un gestor de contraseñas. El problema de fondo es el mismo, una fórmula rápida con poco trabajo por intento. Y pasa lo mismo que en WordPress: subir el coste solo protege a las cuentas que se migran.
/ 10 · Qué hacer
Cómo protegerte mejor
Si tienes cuentas en webs
- Una contraseña distinta por sitio. Si una web la guarda con MD5 y se la roban, esa contraseña cae en segundos. Si es la misma que usas en otros sitios, caen todos.
- Un gestor de contraseñas que las guarde. Así puedes tener una distinta y aleatoria para cada sitio sin memorizarlas. La contraseña maestra, larga y que no uses en ningún otro sitio: en LastPass, la llave de cada caja salía de ella.
- Para las que memorizas, una frase larga y tuya, mejor que algo tipo P@ssw0rd!. Que no esté hecha de piezas que usa cualquiera.
- Segundo factor donde se pueda. No salva la contraseña robada, pero impide entrar solo con ella.
Si haces webs
- bcrypt o Argon2id, y revisa los parámetros: son los que deciden cuánto cuesta cada intento. La guía de OWASP da valores mínimos para cada algoritmo. MD5 y SHA-256 solos no sirven para contraseñas.
- Rehaz los hashes antiguos al iniciar sesión, como hace WordPress 6.8, y decide qué pasa con las cuentas que nunca vuelven.
- Limita los intentos de login y ofrece segundo factor. Eso protege el otro escenario, el de la pantalla de inicio de sesión.
- Mira la columna de contraseñas de tu base de datos al menos una vez. Tarda un minuto.
/ 11 · Método
Cómo se midió y sus límites
- 20 contraseñas no son una muestra. Están elegidas a mano para probar ideas; los resultados describen estas 20, no a todas.
- Las mismas 20, guardadas de las cuatro formas con Python (hashlib, bcrypt y argon2-cffi): MD5 y SHA-256 sin sal, bcrypt con coste 12 y Argon2id con 46 MiB, 1 pasada y 1 hilo.
- Un portátil con una RTX 4060 y hashcat 7.0.0. Las velocidades son las medidas durante el ataque.
- Tres fases por forma de guardar: rockyou con las reglas best66; combinaciones de la lista de 354 piezas con princeprocessor (ninguna de las 20 estaba en ella, comprobado por código); y fuerza bruta por máscara solo para MD5 y SHA-256.
- Tiempo limitado: unos 20 minutos de fuerza bruta en MD5 y SHA-256 (21 y 25 minutos reales), 10 minutos por fase en bcrypt y Argon2id. Que una contraseña no caiga significa que no cayó en ese tiempo.
- Los 35 y 4 días, el 1,4 millones de phpass y los tiempos de fuerza bruta son cálculos, no mediciones.
- Los datos de los CMS y de LastPass salen de las fuentes de abajo y del código publicado de Joomla y PrestaShop, no de este test.
Fuentes
/ Siguiente
Compruebo antes de publicar.
Cada cifra de esta página sale de los registros del ataque y se puede comprobar con los datos descargables. Si tu web guarda contraseñas y no sabes cómo, escríbeme.