Privacy & Security

De qué te protege realmente aplicar hash a una contraseña

El hashing de contraseñas no es magia. Es un mecanismo de control de daños para el día en que se filtre tu tabla de usuarios.

The Wux Webtools Team The Wux Webtools Team 13 min de lectura Asistido por IA, revisado por humanos
Illustration of a password being transformed into a protected hash before storage in a database.
Tabla de contenido
  1. La versión corta
  2. Qué es un hash de contraseña
  3. De qué te protege el hashing
  4. 1. Divulgación inmediata de contraseñas tras una brecha de base de datos
  5. 2. Ataques masivos contra toda tu base de usuarios
  6. 3. Adivinación offline rápida
  7. De qué no te protege el hashing
  8. 1. Phishing
  9. 2. Credential stuffing
  10. 3. Contraseñas capturadas en registros o analíticas
  11. 4. Mala seguridad de sesiones
  12. 5. Restablecimiento de contraseña y recuperación de cuenta débiles
  13. La elección del algoritmo: qué usar ahora
  14. Los factores de coste no se configuran y se olvidan
  15. Peppers: útiles, pero no sustitutos
  16. La lista de comprobación operativa
  17. El modelo mental honesto

La versión corta

Aplicar hash a una contraseña protege a los usuarios cuando te roban la base de datos de contraseñas.

Ese es el cometido principal. No es el único detalle, ni todo el modelo de seguridad, pero sí la razón central por la que aplicamos hash a las contraseñas en lugar de almacenarlas directamente.

Una contraseña correctamente hasheada es difícil de revertir. Si un atacante obtiene una copia de tu tabla de usuarios, no debería descubrir de inmediato que la contraseña de Alice es Spring2026!. En su lugar, obtiene un hash almacenado que requiere tiempo, dinero y hardware para probarlo contra conjeturas.

Esa distinción importa. El hashing de contraseñas no está pensado para hacer que el inicio de sesión sea seguro por sí solo. No detiene el phishing. No impide que alguien pruebe contraseñas filtradas contra tu formulario de inicio de sesión. No protege una cookie de sesión después del inicio de sesión. Compra tiempo y reduce el daño tras un fallo muy concreto: queda expuesto el almacenamiento de tus verificadores de contraseña.

Si entiendes ese límite, tomarás mejores decisiones sobre algoritmos, factores de coste, restablecimientos, registros y respuesta a incidentes.

Qué es un hash de contraseña

Un hash de contraseña es la salida de una función unidireccional aplicada a una contraseña, normalmente con una sal única y un algoritmo de hashing de contraseñas deliberadamente lento.

Cuando un usuario crea una cuenta, el sistema debería hacer aproximadamente esto:

  1. Recibir la contraseña por HTTPS.
  2. Generar una sal aleatoria y única.
  3. Pasar la contraseña y la sal por una función de hashing de contraseñas como Argon2id, bcrypt, scrypt o PBKDF2.
  4. Almacenar el nombre del algoritmo, los parámetros, la sal y el hash resultante.
  5. Descartar la contraseña original.

Cuando el usuario inicia sesión más adelante, el sistema repite el mismo proceso de hashing con la contraseña enviada y los parámetros almacenados. Si el hash resultante coincide con el hash almacenado, el inicio de sesión tiene éxito.

La parte importante: la aplicación no necesita conocer la contraseña original. Solo necesita verificar que la contraseña enviada produce el resultado esperado.

Por eso almacenar contraseñas con cifrado reversible suele ser el modelo equivocado. Si tu aplicación puede descifrar todas las contraseñas, cualquiera que robe la clave de descifrado puede hacer lo mismo. Normalmente, las contraseñas deberían ser no verificables en sentido inverso, no simplemente estar ocultas.

De qué te protege el hashing

1. Divulgación inmediata de contraseñas tras una brecha de base de datos

Si un atacante roba una base de datos que contiene contraseñas en texto plano, el daño es instantáneo. Todas las contraseñas quedan expuestas. Los usuarios están en riesgo no solo en tu sitio, sino en cualquier lugar donde hayan reutilizado esa contraseña.

Si la base de datos contiene contraseñas bien hasheadas, el atacante tiene más trabajo por delante. Debe adivinar contraseñas candidatas, aplicar hash a cada intento con la sal y los parámetros correctos, y comparar el resultado.

Para contraseñas débiles, esto puede seguir siendo rápido. Para contraseñas fuertes y únicas, puede resultar impracticable.

El hashing convierte una divulgación catastrófica en una carrera: ¿pueden los usuarios restablecer sus contraseñas y puedes contener el incidente antes de que los atacantes descifren muchas de ellas?

No es perfecto. Sigue siendo una brecha. Pero es un modo de fallo drásticamente mejor.

2. Ataques masivos contra toda tu base de usuarios

Las sales son una parte clave del almacenamiento de contraseñas porque evitan que los atacantes ataquen eficientemente a muchos usuarios a la vez con tablas precalculadas.

Una sal no es secreta. Se almacena junto al hash. Su función es aportar unicidad.

Si dos usuarios eligen la misma contraseña, las sales únicas garantizan que sus hashes almacenados sean distintos. Eso impide que los atacantes vean de un vistazo que muchos usuarios comparten la misma contraseña. También evita los ataques clásicos con rainbow tables, en los que los atacantes usan enormes listas precalculadas de correspondencias entre contraseñas y hashes.

Sin sales, un hash descifrado puede revelar a todos los usuarios con la misma contraseña. Con sales, cada intento de contraseña debe probarse por separado para cada usuario.

3. Adivinación offline rápida

Una vez que los atacantes tienen una base de datos de contraseñas, pueden adivinar offline. Eso significa que tus límites de tasa de inicio de sesión, CAPTCHA, bloqueo de IP y monitorización ya no importan. El atacante puede probar conjeturas en su propio hardware.

Aquí es donde importa la elección del algoritmo.

Los hashes de propósito general como SHA-256 y SHA-512 están diseñados para ser rápidos. Eso es bueno para la integridad de archivos y las firmas digitales. Es malo para el almacenamiento de contraseñas.

Los algoritmos de hashing de contraseñas están diseñados para ser lentos, ajustables y, a veces, exigentes en memoria. Argon2id, bcrypt, scrypt y PBKDF2 permiten ajustar parámetros de coste para que cada intento requiera un tiempo significativo.

Argon2id se recomienda ampliamente para sistemas nuevos porque puede configurarse para requerir tanto tiempo de CPU como memoria, lo que encarece el cracking a gran escala con GPU. bcrypt sigue siendo común y aceptable cuando se configura bien, aunque tiene limitaciones como el manejo de la longitud de las contraseñas. PBKDF2 todavía se usa en algunos entornos impulsados por cumplimiento normativo, especialmente donde se requieren componentes validados por FIPS.

El principio es simple: hacer que los inicios de sesión legítimos sean aceptablemente rápidos, mientras se encarecen miles de millones de intentos.

De qué no te protege el hashing

1. Phishing

Si un usuario escribe su contraseña en una página de inicio de sesión falsa, el hashing en tu servidor no ayuda. El atacante recibe la contraseña antes de que tu sistema llegue a verla.

Las defensas aquí son distintas: autenticación multifactor, passkeys, educación de usuarios, higiene de dominios, autenticación resistente al phishing y flujos cuidadosos de restablecimiento de contraseña.

El hashing de contraseñas es una red de seguridad para secretos almacenados. No es una defensa contra que los usuarios sean engañados para entregar esos secretos.

2. Credential stuffing

El credential stuffing ocurre cuando los atacantes toman pares de nombre de usuario y contraseña filtrados de un servicio y los prueban en otro.

Tus hashes de contraseña pueden ser excelentes, y el credential stuffing aun así puede funcionar si los usuarios reutilizan contraseñas.

Este es un ataque online contra tu formulario de inicio de sesión, no un ataque offline contra tu base de datos. Necesitas límites de tasa, detección de anomalías, comprobaciones de contraseñas filtradas, MFA y políticas de bloqueo sensatas que no creen oportunidades fáciles de denegación de servicio.

El mismo pensamiento práctico se aplica a cualquier formulario expuesto. Si estás revisando tu superficie de autenticación, merece la pena leer por qué tu formulario de contacto es tu mayor responsabilidad de spam; la mecánica difiere, pero la lección es similar: las entradas públicas necesitan controles contra abuso, no solo código backend limpio.

3. Contraseñas capturadas en registros o analíticas

El hashing solo ayuda si la contraseña en texto plano se descarta rápidamente y nunca se copia en otro lugar.

Los fallos comunes incluyen:

  • Registrar cuerpos de solicitud completos en intentos fallidos de inicio de sesión.
  • Enviar contraseñas a herramientas de monitorización de errores.
  • Capturar campos de contraseña en productos de reproducción de sesión.
  • Incluir credenciales en URLs durante flujos de restablecimiento o migración mal diseñados.
  • Almacenar contraseñas temporales en texto plano durante importaciones.

Estos errores omiten por completo el hashing de contraseñas. Si el texto plano acaba en registros, copias de seguridad, almacenes de datos o herramientas de terceros, tu función de hash es irrelevante.

Trata los campos de contraseña como datos tóxicos. Redáctalos antes de registrar. Exclúyelos de analíticas. Mantenlos fuera de las URLs. Limita quién puede acceder a trazas de producción.

4. Mala seguridad de sesiones

Después del inicio de sesión, el navegador del usuario suele recibir una cookie o token de sesión. Si ese token es robado, es posible que el atacante no necesite la contraseña en absoluto.

El hashing de contraseñas no protege contra cross-site scripting, cookies inseguras, fijación de sesión, generación débil de tokens ni vidas de sesión demasiado largas.

Las cookies de sesión merecen su propia revisión: HttpOnly, Secure, SameSite apropiado, sesiones de alto riesgo de corta duración e invalidación del lado del servidor al cambiar la contraseña. El panorama más amplio de privacidad y navegadores también sigue cambiando, como se explica en qué cambió para las cookies en 2026.

5. Restablecimiento de contraseña y recuperación de cuenta débiles

Muchas tomas de control de cuentas no empiezan con la contraseña. Empiezan con el flujo de restablecimiento.

Si los tokens de restablecimiento son predecibles, de larga duración, se filtran mediante cabeceras de referencia o se envían a cuentas de correo comprometidas, el hashing de contraseñas no te salvará.

Usa tokens de restablecimiento de alta entropía, ventanas de expiración cortas, uso único y notificaciones claras al usuario. Como el correo electrónico suele ser el canal de recuperación, la autenticación básica del dominio también importa. Si tu equipo trata los registros DNS como una ceremonia misteriosa, empieza con un recorrido amigable para desarrolladores por MX, SPF, DKIM y DMARC.

La elección del algoritmo: qué usar ahora

Para aplicaciones nuevas, usa Argon2id si tu plataforma lo soporta bien. Es el ganador de la Password Hashing Competition y está diseñado para el almacenamiento de contraseñas, incluida la resistencia al cracking intensivo con GPU.

Una jerarquía moderna razonable se ve así:

  1. Argon2id para sistemas nuevos donde esté disponible.
  2. bcrypt cuando Argon2id no sea práctico y el soporte de bcrypt sea maduro.
  3. scrypt cuando la configuración exigente en memoria esté bien soportada.
  4. PBKDF2 cuando lo exijan la plataforma o restricciones de cumplimiento.

Evita SHA-256, SHA-512, MD5 en crudo, o una combinación casera como sha256(password + salt). Los hashes rápidos no son funciones de almacenamiento de contraseñas. Las construcciones personalizadas ingeniosas tienden a ser peores que las estándar y aburridas.

También evita inventar tu propia política de contraseñas alrededor de detalles triviales del algoritmo. Los usuarios no se benefician de una lista de comprobación de composición de contraseñas con 12 reglas si eso los empuja hacia patrones predecibles. Las contraseñas más largas y únicas, los gestores de contraseñas, el cribado de contraseñas filtradas y MFA suelen importar más.

Los factores de coste no se configuran y se olvidan

El hashing de contraseñas tiene parámetros. Argon2id tiene memoria, iteraciones y paralelismo. bcrypt tiene un factor de coste. PBKDF2 tiene un recuento de iteraciones.

Estos valores deben elegirse en función de tu entorno de producción. Demasiado bajos, y los atacantes adivinan barato. Demasiado altos, y tu sistema de inicio de sesión se vuelve lento o vulnerable a denegación de servicio.

Un objetivo práctico suele estar en el rango de decenas a unos pocos cientos de milisegundos por verificación de contraseña en tus servidores reales, según el tráfico y el riesgo. Los sistemas de alta seguridad pueden elegir más. Los sistemas a escala de consumo pueden necesitar una planificación cuidadosa de capacidad.

No copies un factor de coste de una entrada de blog de hace cinco años. El hardware cambia. Las bibliotecas cambian. Tu tráfico cambia.

Revisa los parámetros periódicamente y planifica el rehashing. Un patrón común es almacenar el algoritmo y los parámetros con cada hash. En un inicio de sesión correcto, si los parámetros almacenados están obsoletos, vuelve a aplicar hash a la contraseña enviada con la configuración más reciente y actualiza el registro.

Peppers: útiles, pero no sustitutos

Un pepper es un valor secreto añadido al proceso de hashing de contraseñas y almacenado por separado de la base de datos, a menudo en un gestor de secretos o en un módulo de seguridad hardware.

A diferencia de una sal, un pepper debe permanecer secreto.

Los peppers pueden reducir el daño si se filtra la base de datos pero no los secretos de la aplicación. Son más útiles en entornos maduros con buena gestión de claves. Son menos útiles si el mismo atacante puede robar tanto la base de datos como la configuración de la aplicación.

Si usas un pepper, planifica cuidadosamente la rotación. Rotarlo puede requerir que los usuarios vuelvan a iniciar sesión o restablezcan sus contraseñas, según el diseño. Un pepper es una capa adicional, no una razón para debilitar la configuración del hash subyacente.

La lista de comprobación operativa

Si eres responsable de un sistema real, la lista de comprobación práctica es corta:

  • Almacena contraseñas solo con un algoritmo estándar de hashing de contraseñas.
  • Usa una sal aleatoria y única por contraseña.
  • Prefiere Argon2id para nuevos desarrollos.
  • Ajusta los parámetros de coste en hardware similar al de producción.
  • Almacena el algoritmo y los parámetros con cada hash.
  • Vuelve a aplicar hash al iniciar sesión cuando los parámetros queden obsoletos.
  • Nunca registres contraseñas ni las envíes a herramientas de analíticas.
  • Usa TLS en todos los lugares donde se envíen credenciales.
  • Añade MFA o passkeys cuando el riesgo lo justifique.
  • Protege los flujos de restablecimiento con la misma seriedad que los flujos de inicio de sesión.
  • Ten un plan de incidentes para restablecimientos forzados y notificación a usuarios.

El hashing de contraseñas no es glamuroso. Es fontanería. Pero es el tipo de fontanería que determina si una brecha se convierte en un incidente doloroso o en un desastre para todos los usuarios.

<!-- tool-cta:start -->

💡 Prueba esto: Mira cómo la misma entrada se asigna a distintos algoritmos con el Hash Generator, que hace concreta la diferencia entre hashes rápidos y hashes aptos para contraseñas.

<!-- tool-cta:end -->

El modelo mental honesto

La mejor forma de pensar en el hashing de contraseñas es esta:

El hashing no protege la contraseña mientras el usuario la está escribiendo. No protege la cuenta después de que el usuario haya iniciado sesión. No protege a los usuarios que reutilizan contraseñas en la web.

Protege el verificador almacenado.

Eso suena limitado, pero es extremadamente importante. Las bases de datos se filtran. Las copias de seguridad se filtran. Los sistemas de staging se copian. Los proveedores obtienen accesos que no deberían tener. Exportaciones antiguas permanecen en almacenamiento de objetos más tiempo del que nadie recuerda.

Cuando eso ocurre, el diseño de tu almacenamiento de contraseñas marca la diferencia entre que los atacantes reciban contraseñas y que reciban un problema de adivinación costoso.

Eso es de lo que realmente te protege aplicar hash a una contraseña.

Preguntas frecuentes

¿SHA-256 es suficiente para almacenar contraseñas si añado una sal?
No. Una sal es necesaria, pero SHA-256 sigue siendo demasiado rápido. El almacenamiento de contraseñas necesita una función lenta y ajustable como Argon2id, bcrypt, scrypt o PBKDF2.
¿Las contraseñas deberían cifrarse en lugar de hashearse?
Normalmente no. El cifrado es reversible, lo que significa que una clave robada puede exponer todas las contraseñas. Normalmente, las contraseñas deberían almacenarse como hashes no reversibles.
¿Cuál es la diferencia entre una sal y un pepper?
Una sal es un valor único y no secreto almacenado con cada hash de contraseña. Un pepper es un secreto compartido almacenado por separado de la base de datos. Las sales son obligatorias; los peppers son opcionales y más complejos operativamente.
¿El hashing de contraseñas protege contra el credential stuffing?
No. El credential stuffing es un ataque online que usa contraseñas filtradas de otros servicios. Necesitas límites de tasa, comprobaciones de contraseñas filtradas, MFA y monitorización para reducir ese riesgo.
¿Necesito volver a aplicar hash a contraseñas antiguas?
A menudo, sí. Almacena los parámetros de hash con cada registro de contraseña y luego vuelve a aplicar hash después de un inicio de sesión correcto cuando el algoritmo o la configuración de coste estén obsoletos.

Fuentes y lecturas adicionales

  1. OWASP Password Storage Cheat Sheet
  2. NIST Special Publication 800-63B: Digital Identity Guidelines
  3. RFC 9106: Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications
  4. Have I Been Pwned: Pwned Passwords
Sobre el autor
The Wux Webtools Team

Última actualización:

Sigue leyendo