# ADR-003: Hashing de Contraseñas ## Estado Aceptado ## Fecha 2026-05-06 ## Contexto Necesitamos guardar contraseñas de usuarios de forma segura. La decisión debe considerar: - Resistencia a ataques de fuerza bruta y rainbow tables - Performance (se ejecuta en cada login y cambio de password) - Compatibilidad con estándares de la industria ## Decisión Usar **bcrypt** con cost factor 12 para hashing de contraseñas. ## Justificación 1. **bcrypt** es diseñado específicamente para password hashing lento 2. **Cost factor configurable**: permite aumentar resistencia en el futuro 3. **Resistente a GPU/rainbow attacks**: diseñado para ser lento intencionalmente 4. **Incorpora salt**: cada password tiene salt único, evitando rainbow tables 5. **Estándar de industria**: ampliamente usado (Django, Rails, bcrypt) ## Consecuencias ### ✅ Positivas - Resistente a ataques de fuerza bruta - Salt automático evitar rainbow tables - Configurable (cost factor) - Librerías maduras en todos los lenguajes ### ❌ Negativas - Más lento que MD5/SHA (es el punto, pero afecta latency) - Enorme payload si se guarda en cookies/token ### 🔄 Neutrales - Requiere Python 3.11+ para bcrypt moderno ## Implementación ```python import bcrypt def hash_password(password: str) -> str: """Hash password with bcrypt, cost 12.""" return bcrypt.hashpw( password.encode('utf-8'), bcrypt.gensalt(rounds=12) ).decode('utf-8') def verify_password(password: str, hashed: str) -> bool: """Verify password using constant-time comparison.""" return bcrypt.checkpw( password.encode('utf-8'), hashed.encode('utf-8') ) ``` ## Alternativas Consideradas ### Opción A: SHA-256 (con salt) - **Pros**: Rápido, simple - **Contras**: No es lento, vulnerable a GPU attacks, diseñado para speed no security - **Razón de descarte**: No es resistente a hardware moderno ### Opción B: Argon2 - **Pros**: Ganador PHC 2015, configurable memory/CPU - **Contras**: Más complejo de implementar, menos soporte de librerías - **Razón de descarte**: bcrypt es más simple y suficiente para nuestro caso de uso ### Opción C: scrypt - **Pros**: Diseñado para ser memory-hard - **Contras**: Más lento de configurar, configuración compleja - **Razón de descarte**: bcrypt es más simple y ampliamente soportado ## Notas - Si en el futuro,我们需要 mayor seguridad, migrar a Argon2 - No guardar passwords en logs bajo ninguna circunstancia ## Relacionado con - Feature F-003 - Componente: PasswordService