← El notebookIssue №20Herramientas7 min lecturaFeb 10, 2026

Cómo generar y manejar contraseñas seguras.

La mayoría de contraseñas son inseguras por las mismas razones de siempre. Los patrones correctos para generar, almacenar y manejar credenciales.

G
Steven Galo
Fundador · Costa Rica
🔐

Entropía y fortaleza.

La fortaleza de una contraseña se mide en bits de entropía: qué tan difícil sería adivinarla por fuerza bruta. Una contraseña de 8 caracteres solo con letras tiene unos 45 bits de entropía. Una de 16 caracteres alfanuméricos tiene más de 95 bits. Para contexto: con hardware moderno, 45 bits se rompen en minutos. 95 bits tardarían más de la edad del universo.

La longitud importa más que la complejidad. "correctohorsestaple" (cuatro palabras al azar) es más segura que "P@ssw0rd!" aunque esta última parezca más compleja.

8 chars alfanum
~45 bits
16 chars random
~95 bits
Seguro desde
80 bits

Cómo generar contraseñas.

El error más común es usar Math.random() para generar contraseñas. Math.random() no es criptográficamente seguro. Para contraseñas reales, usá crypto.getRandomValues() en el browser o crypto.randomBytes() en Node.js.

// Browser / Node.js moderno
function generatePassword(length = 16): string {
  const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
  const array = new Uint32Array(length);
  crypto.getRandomValues(array);
  return Array.from(array, n => charset[n % charset.length]).join('');
}

Para generar passphrases (más fáciles de recordar y muy seguras), usá una lista de palabras como EFF Diceware y seleccioná al menos 5 palabras al azar.

Cómo almacenarlas.

Nunca almacenés contraseñas en texto plano. Nunca uses MD5 o SHA-1 para hashear contraseñas. Estas funciones son rápidas, lo que las hace vulnerables a ataques de fuerza bruta. En cambio, usá algoritmos diseñados específicamente para contraseñas: bcrypt, Argon2 o scrypt. Son lentos por diseño.

import bcrypt from 'bcrypt';

// Al guardar la contraseña:
const SALT_ROUNDS = 12; // más alto = más lento y más seguro
const hash = await bcrypt.hash(plainPassword, SALT_ROUNDS);
await db.user.update({ where: { id }, data: { passwordHash: hash } });

// Al verificar:
const isValid = await bcrypt.compare(plainPassword, storedHash);
if (!isValid) throw new Error('Contraseña incorrecta');
Si tu base de datos fuera robada mañana, ¿cuánto tiempo tendría un atacante para acceder a las cuentas de tus usuarios? Con bcrypt y salt_rounds=12, la respuesta es "suficiente para que los usuarios cambien sus contraseñas."

Gestores de contraseñas.

Para uso personal, un gestor de contraseñas no es opcional si querés seguridad real. Las mejores opciones en 2026: Bitwarden (código abierto, gratis, self-hosteable), 1Password (mejor UX, ideal para teams) y KeePassXC (local, sin nube, máximo control). Evitá guardar contraseñas en el browser — si alguien accede a tu computadora, tiene acceso a todo.

Implementación en código.

Algunos patrones adicionales para aplicaciones robustas: implementá rate limiting en endpoints de login (máximo 5 intentos por minuto por IP), invalidá todas las sesiones cuando el usuario cambia su contraseña, usá HTTPS siempre para que las contraseñas nunca viajen en texto plano, y considerá implementar autenticación de dos factores (2FA) con TOTP para cuentas con acceso a datos sensibles.

— Construido en público

¿Tienes una
sugerencia?

Seguimos construyendo. Si tienes una idea para una herramienta o un tema para el blog, escríbenos directamente o abre un issue en GitHub.