bcrypt vs Argon2: elegir parámetros de hashing de contraseñas
bcrypt vs Argon2 explicado: compara rasgos de seguridad, costes de rendimiento en escenarios reales y cómo elegir parámetros seguros para backends web modernos.

Qué problema resuelve el hash de contraseñas
El hashing de contraseñas permite que un backend guarde una contraseña sin almacenar la contraseña en sí. Cuando alguien se registra, el servidor pasa la contraseña por una función unidireccional y guarda el resultado (el hash). Al iniciar sesión, se hashea la contraseña que escribió el usuario y se compara con lo almacenado.
Un hash no es cifrado. No hay forma de revertirlo. Esa propiedad unidireccional es exactamente por lo que se usa el hashing para contraseñas.
Entonces, ¿por qué no usar un hash rápido normal como SHA-256? Porque rápido es lo que quieren los atacantes. Si se filtra una base de datos, los atacantes no prueban contraseñas intentando ingresar una por una en el sitio. Adivinan offline usando la lista de hashes robada, empujando intentos al ritmo que les permita su hardware. Con GPUs, los hashes rápidos se pueden probar a enorme escala. Incluso con salts únicos, un hash rápido sigue siendo barato de forzar por fuerza bruta.
Aquí está el modo de falla realista: una pequeña aplicación web pierde su tabla de usuarios en una brecha. El atacante obtiene correos y hashes de contraseñas. Si esos hashes se generaron con una función rápida, las contraseñas comunes y pequeñas variaciones caen rápidamente. Luego el atacante prueba la misma contraseña en otros sitios (credential stuffing), o la usa para acceder a funciones de mayor privilegio dentro de tu app.
Un buen hash de contraseña hace que adivinar sea caro. El objetivo no es “inquebrantable”. El objetivo es “demasiado lento y costoso para merecer la pena”.
Una configuración de hashing de contraseñas debería ser:
- Unidireccional (verificar, no revertir)
- Lenta por intento
- Costosa para hardware paralelo (especialmente GPUs)
- Lo bastante rápida para que los inicios de sesión reales sigan pareciendo normales
- Ajustable para poder aumentar el costo con el tiempo
bcrypt y Argon2, en un minuto
Cuando comparas bcrypt vs Argon2, estás eligiendo cómo quieres ralentizar la adivinación de contraseñas después de una fuga de base de datos.
bcrypt es la opción más antigua y ampliamente soportada. Está diseñado para ser costoso en la CPU y tiene una única perilla principal: el factor de costo. También es “aburrido” en buen sentido: fácil de encontrar en bibliotecas, fácil de desplegar y predecible.
Argon2 es más nuevo y fue diseñado para ser memory-hard. Puede forzar que cada intento de contraseña use una cantidad significativa de RAM, no solo CPU. Eso importa porque los atacantes a menudo ganan ejecutando un gran número de intentos en paralelo en GPUs o hardware especializado. La memoria es más difícil y cara de escalar a ese nivel de paralelismo.
Argon2 tiene tres variantes:
- Argon2i: enfatiza la resistencia a ciertos ataques por canales laterales
- Argon2d: enfatiza la resistencia a GPUs, con más consideraciones sobre canales laterales
- Argon2id: una mezcla práctica de ambos, y la opción por defecto común para hashing de contraseñas
Si tu stack soporta Argon2id y puedes ajustar la memoria de forma segura, suele ser la mejor opción moderna. Si necesitas máxima compatibilidad con sistemas antiguos, bcrypt sigue siendo una buena elección cuando se configura con un factor de costo lo bastante alto.
Propiedades de seguridad que importan
La pregunta central es simple: si un atacante roba la base de datos de contraseñas, ¿cuánto cuesta adivinar contraseñas a escala?
Con bcrypt, controlas el costo (work factor). Mayor costo significa que cada intento tarda más. Eso ralentiza a los atacantes y también retrasa tus propias comprobaciones de inicio de sesión, así que lo ajustas hasta un punto que sea doloroso para los atacantes pero aceptable para los usuarios.
Con Argon2id, puedes añadir memory-hardness además del costo en tiempo. Cada intento necesita tiempo de CPU y RAM accesada en un patrón específico. Las GPUs pueden ser extremadamente rápidas en trabajo intensivo de cómputo, pero pierden mucha ventaja cuando cada intento paralelo requiere memoria sustancial.
Los salts son innegociables. Un salt único y aleatorio por contraseña:
- evita que tablas precomputadas se reutilicen en toda la base de datos
- asegura que contraseñas idénticas no produzcan hashes idénticos entre usuarios
Los salts no hacen fuertes a las contraseñas débiles. Principalmente te protegen después de una fuga forzando al atacante a hacer trabajo real por cada usuario.
Fortalezas y límites de bcrypt que debes conocer
bcrypt sigue usándose mucho, sobre todo porque es fácil de desplegar en cualquier lugar. Suele encajar bien cuando necesitas amplia interoperabilidad, cuando tu stack tiene opciones criptográficas limitadas o cuando quieres una única palanca de ajuste.
El mayor “pitfall” es el límite de 72 bytes. bcrypt solo usa los primeros 72 bytes de la contraseña e ignora el resto. Esto puede sorprender a quien usa frases largas o gestores de contraseñas.
Si eliges bcrypt, deja explícito el comportamiento respecto a la longitud de la contraseña. O bien impones una longitud máxima (en bytes, no en caracteres) o manejas las entradas largas de forma consistente entre todos los servicios. Lo importante es evitar la truncación silenciosa que cambia lo que el usuario cree que es su contraseña.
bcrypt también es menos resistente al hardware moderno de cracking paralelo que las opciones memory-hard. Su defensa sigue siendo válida, pero depende mucho de elegir un factor de costo que mantenga cada intento caro.
Si estás construyendo un sistema nuevo o tienes cuentas de alto valor (planes de pago, roles de administrador), migrar los nuevos hashes a Argon2id mientras sigues aceptando hashes bcrypt existentes hasta que los usuarios inicien sesión es una vía común y de bajo riesgo.
Fortalezas y compensaciones de Argon2
Argon2 fue creado para hashing de contraseñas. Argon2id es la variante que la mayoría de equipos elige porque equilibra la resistencia a GPUs con una protección razonable contra canales laterales.
Argon2id te da tres parámetros:
- Memoria (m): cuánta RAM usa cada hash mientras corre
- Tiempo/iteraciones (t): cuántas pasadas hace sobre esa memoria
- Paralelismo (p): cuántas “lanes” usa (ayuda en CPUs multi-núcleo)
La memoria es la principal ventaja. Si cada intento requiere una cantidad significativa de RAM, los atacantes no pueden ejecutar tantos intentos en paralelo sin pagar mucho por capacidad y ancho de banda de memoria.
El inconveniente es operativo: más memoria por hash significa menos inicios de sesión concurrentes antes de que tus servidores sientan presión. Si fijas la memoria demasiado alta, los picos de login pueden causar colas, timeouts o incluso fallos por falta de memoria. También debes pensar en el abuso: muchos intentos concurrentes pueden convertirse en un problema de recursos si no limitas el trabajo.
Para mantener Argon2id seguro y usable, ajústalo como una característica de rendimiento:
- haz benchmarks en hardware parecido al de producción
- limita el trabajo de hashing concurrente (cápsulas de trabajadores, colas)
- aplica límites de frecuencia y bloqueos ante fallos repetidos
- mantén parámetros consistentes entre servicios para que un endpoint débil no sea el objetivo
Costes de rendimiento en backends web reales
Con el hashing de contraseñas, “más rápido es mejor” suele ser la meta equivocada. Quieres que cada intento sea caro para los atacantes mientras que los inicios de sesión sigan sintiéndose ágiles para los usuarios reales.
Una manera práctica de fijarlo es un presupuesto de tiempo por verificación en tu hardware real de producción. Muchos equipos apuntan a algo como 100 a 300 ms por verificación, pero el número correcto depende de tu tráfico y servidores. La diferencia entre bcrypt y Argon2 es en qué estás gastando: bcrypt es mayormente tiempo de CPU, mientras que Argon2 también puede reservar memoria.
Elige un tiempo objetivo y luego mide
Elige un tiempo objetivo por hash y pruébalo en condiciones parecidas a producción. Mide tanto el hashing en registro/cambio de contraseña como la verificación de login, pero trata el login como la ruta crítica.
Un plan de medición ligero:
- prueba 1, 10 y 50 verificaciones concurrentes y registra latencias p50 y p95
- repite ejecuciones para reducir ruido por caching y boosting de CPU
- mide la llamada a la base de datos por separado para saber cuánto cuesta realmente el hashing
- prueba con el mismo contenedor y límites de CPU que vas a desplegar
Los picos importan más que las medias
La mayoría de sistemas falla durante los picos. Si un correo promocional envía una ola de usuarios a la página de login, tus parámetros de hashing deciden si el sistema sigue siendo usable.
Si una verificación tarda 250 ms y tu servidor aguanta 40 en paralelo antes de encolarse, una ráfaga de 500 intentos de login puede convertirse en esperas de varios segundos. En esa situación, una pequeña reducción de costo junto con límites de frecuencia estrictos puede mejorar la seguridad real más que empujar los parámetros hasta volver frágil el endpoint de login.
Mantén el login interactivo predecible
No todas las operaciones de contraseña necesitan la misma urgencia. Mantén el coste del login interactivo estable y haz el trabajo pesado fuera del camino crítico. Un patrón común es rehash-on-login (actualizar el hash de un usuario justo después de un login exitoso) o trabajos en segundo plano para migraciones e importaciones.
Cómo elegir parámetros paso a paso
El ajuste de parámetros consiste en aumentar el coste para el atacante por intento sin hacer que los inicios de sesión sean lentos o que desestabilicen tus servidores.
-
Elige un algoritmo bien soportado por tu stack. Si Argon2id está disponible y bien soportado, suele ser la elección por defecto. Si necesitas amplia compatibilidad, bcrypt sigue estando bien.
-
Fija un tiempo objetivo por hash en hardware parecido a producción. Escoge algo que mantenga los logins fluidos durante carga pico.
-
Ajusta para alcanzar ese tiempo. Con bcrypt, sube el factor de costo. Con Argon2id, equilibra memoria, iteraciones y paralelismo. La memoria es la palanca que cambia más la economía para el atacante.
-
Almacena el algoritmo y los parámetros con el hash. La mayoría de formatos estándar de hash embeben estos detalles. También asegúrate de que el campo de la base de datos sea lo bastante largo para que los hashes nunca se trunquen.
-
Planifica actualizaciones con rehash-on-login. Cuando un usuario inicia sesión, si su hash almacenado usa parámetros más débiles que tu política actual, rehasea y reemplaza.
Un punto de partida práctico
Si necesitas una base antes de medir, comienza con conservador y ajusta según tiempos.
- Para bcrypt, muchos equipos empiezan alrededor del factor 12 y lo ajustan según mediciones reales.
- Para Argon2id, un punto de partida común es memoria en decenas a unos pocos cientos de MB, costo de tiempo 2 a 4 e paralelismo 1 a 2.
Trata estas cifras como puntos de partida, no reglas. Los parámetros correctos son los que encajan con tu tráfico, hardware y picos de login.
Errores comunes que debilitan el almacenamiento de contraseñas
La mayoría de fallos en el almacenamiento de contraseñas vienen de huecos de configuración, no de un algoritmo roto.
Errores con salts son un gran ejemplo. Cada contraseña necesita su propio salt único almacenado con el hash. Reusar salts, o usar un salt global para todos los usuarios, facilita que los atacantes reaprovechen trabajo y comparen cuentas.
Negligencia del costo es otra. Los equipos a menudo lanzan con un costo bajo porque el login se siente más rápido y nunca lo revisan. El hardware mejora, los atacantes escalan, y tus ajustes antes razonables se vuelven baratos.
Sobreajustar Argon2 también es común. Fijar la memoria extremadamente alta puede verse bien en papel, pero luego causar logins lentos, colas de peticiones o errores por falta de memoria durante picos reales.
El manejo de la longitud de contraseña importa, especialmente con el comportamiento de 72 bytes de bcrypt. Si permites contraseñas largas pero las trunacas silenciosamente, creas comportamiento confuso y reduces seguridad.
Unos hábitos prácticos previenen la mayoría de esto:
- usa salts únicos por contraseña (deja que la biblioteca los genere)
- carga pruebas de estrés y revisa parámetros periódicamente
- ajusta la memoria de Argon2 pensando en tráfico pico, no solo en benchmarks de un solo login
- deja explícitos y consistentes los límites de longitud de contraseña
- pon límites de concurrencia y monitorización alrededor del endpoint de login
Lista rápida para una configuración más segura
Mantén esta lista cerca cuando despliegues y cuando cambies infraestructura:
- Salt único por contraseña, generado aleatoriamente y almacenado con el hash
- Costo de hashing que resista tráfico pico, verificado con pruebas de carga en hardware parecido a producción
- Parámetros almacenados con el hash, para poder verificar cuentas antiguas y subir el costo más tarde
- Controles contra ataques online, incluyendo límites de frecuencia y bloqueos cortos por fallos repetidos
- Un camino de actualización, normalmente rehash-on-login
Una comprobación sencilla: ejecuta una prueba en staging que incluya una ráfaga de logins (exitosos y fallidos) y observa la latencia end-to-end, CPU y uso de RAM. Si la ruta de login sufre, ajusta el costo y aprieta los límites de frecuencia. No “arregles” quitando elementos esenciales como los salts.
Un ejemplo realista: afinando para una pequeña app web
Imagina una pequeña SaaS con unos pocos miles de usuarios. La mayor parte del día hay tráfico estable, pero ves ráfagas cortas de logins tras un boletín o al inicio del día laboral. Ahí es donde la elección se convierte en planificación de capacidad.
Eliges Argon2id para aumentar el coste del cracking offline. Fija un tiempo objetivo de verificación en tu hardware real (por ejemplo, 100–250 ms), luego ajusta parámetros para alcanzarlo vigilando la RAM, porque la configuración de memoria puede limitar cuántos logins puedes procesar a la vez.
Un bucle práctico de ajuste se ve así:
- empieza con iteraciones y paralelismo modestos
- aumenta la memoria hasta que la concurrencia resulte incómoda
- ajusta las iteraciones para afinar el coste en tiempo
- vuelve a probar con ráfagas simuladas, no solo con peticiones únicas
Si ya tienes hashes antiguos con parámetros más débiles, sigue verificándolos pero actualiza silenciosamente. Tras un login exitoso, rehasea con los parámetros actuales y guarda el nuevo valor. Con el tiempo, los usuarios activos migran a hashes más fuertes sin resets forzosos.
Tras el lanzamiento, monitoriza el login como cualquier endpoint crítico: latencia en cola (p95/p99), CPU y RAM durante picos, picos de fallos de login y qué tan rápido se reemplazan los hashes antiguos.
Próximos pasos: desplegar de forma segura y mejorar continuamente
Escribe tu política y trátala como un ajuste vivo. Por ejemplo: “Argon2id con X memoria, Y iteraciones, Z paralelismo” o “factor bcrypt N”, más la fecha en que se eligió y cuándo la revisarás (cada 6 a 12 meses es un buen punto de partida).
Mantén un camino de actualización para no quedarte atascado con hashes antiguos. Rehash-on-login es simple y funciona bien en la mayoría de sistemas.
Un hash fuerte ayuda, pero no sustituye los controles online contra abuso. Límites de frecuencia, bloqueos y flujos de restablecimiento de contraseña cuidados importan tanto para la seguridad real.
Si construyes tu backend con una plataforma sin código como AppMaster, vale la pena comprobar que su módulo de autenticación usa hashing fuerte por defecto y que el costo de hashing esté ajustado en el mismo tipo de infraestructura donde desplegarás. Esa pequeña prueba inicial suele marcar la diferencia entre “seguro y fluido” y “seguro pero inutilizable bajo carga”.
FAQ
Password hashing lets you verify a login without storing the actual password. You store a one-way hash, then hash the user’s input and compare the results; if your database leaks, attackers still have to guess passwords instead of reading them.
Encryption is reversible with a key, so if that key is stolen or mismanaged, passwords can be recovered. Hashing is one-way by design, so even you can’t “decrypt” the stored value back into the original password.
Fast hashes are great for attackers because they can try guesses offline at very high speed, especially with GPUs. Password hashes should be intentionally slow (and ideally memory-hard) so large-scale guessing becomes expensive.
A salt is a unique, random value stored alongside each password hash. It prevents identical passwords from producing identical hashes and stops attackers from reusing precomputed tables, but it does not make weak passwords strong by itself.
Pick Argon2id if your stack supports it well and you can tune memory safely, because it’s designed to resist parallel cracking. Choose bcrypt when you need maximum compatibility and a simpler tuning model, and then set a sufficiently high cost factor.
bcrypt has a 72-byte limit: it only uses the first 72 bytes of a password and ignores the rest. To avoid surprises, enforce a clear max length in bytes or handle long inputs consistently so users don’t get silent truncation.
Memory is the main lever because it limits how many guesses attackers can run in parallel without paying heavily for RAM and bandwidth. Too much memory can also hurt you by reducing how many logins your servers can process at once, so you tune for peak traffic, not just single tests.
Aim for a predictable verification time on your real deployment hardware, often around 100–300 ms per check, then load-test concurrency. The right setting is the one that stays responsive during login bursts while still making offline guessing costly.
Store the algorithm and its parameters with the hash so you can verify old users and raise cost later. A common approach is rehash-on-login: after a successful login, if the stored hash is weaker than your current policy, recompute it with the new settings and save it.
Common failures include missing or reused salts, shipping with a low cost and never revisiting it, and over-tuning Argon2 memory until logins time out during spikes. Also watch for password length handling issues (especially with bcrypt) and protect the login endpoint with rate limits and short lockouts.


