SHA-256 vs bcrypt vs Argon2 - Comparacion Completa de Algoritmos de Hashing para Desarrolladores
Aprende por que no debes usar SHA-256 para almacenar contrasenas, las diferencias entre bcrypt y Argon2, y la estrategia de hashing recomendada para 2026.
Toolypet Team
Development Team
SHA-256 vs bcrypt vs Argon2: Cuando Usar Cada Uno?
"Si hasheo las contrasenas con SHA-256 y las almaceno, deberia ser seguro, no?"
Muchos desarrolladores hacen esta pregunta. La conclusion es: no debes usar SHA-256 para contrasenas.
Esta guia explica las diferencias entre los algoritmos de hashing y la eleccion correcta para cada situacion.
Hashing vs Encriptacion: Conceptos Basicos
Hashing
Entrada → Funcion Hash → Salida de longitud fija (irreversible)
"password" → SHA-256 → "5e884898da28047d..."
- Unidireccional: No se puede recuperar el original
- Deterministico: Misma entrada = Misma salida
- Longitud fija: Tamano de salida independiente del tamano de entrada
Encriptacion
Entrada + Clave → Encriptacion → Texto cifrado → Desencriptacion + Clave → Original
"password" + key → AES → "Xyz..." → AES + key → "password"
- Bidireccional: Original recuperable con clave
- Dependiente de clave: No se puede desencriptar sin clave
Usa hashing para almacenamiento de contrasenas. No necesitas el original — solo compara el valor de entrada con el hash.
Clasificacion de Algoritmos de Hashing
Hash Rapido
| Algoritmo | Longitud de Salida | Velocidad | Caso de Uso |
|---|---|---|---|
| MD5 | 128 bits | Muy rapido | ❌ No usar para seguridad |
| SHA-1 | 160 bits | Rapido | ❌ No usar para seguridad |
| SHA-256 | 256 bits | Rapido | Integridad de archivos, firmas digitales |
| SHA-512 | 512 bits | Rapido | Integridad de archivos, blockchain |
Hash Lento (Hash de Contrasenas)
| Algoritmo | Caracteristicas | Recomendacion 2026 |
|---|---|---|
| bcrypt | Tiempo ajustable (cost) | ✅ |
| scrypt | Intensivo en memoria | ✅ |
| Argon2 | Mas reciente, OWASP #1 | ✅✅ |
| PBKDF2 | Alta compatibilidad | ⚠️ Legado |
Por Que No Debes Almacenar Contrasenas con SHA-256?
Razon 1: Demasiado Rapido
SHA-256 esta disenado para velocidad. Esto es una ventaja para verificacion de integridad de archivos, pero un defecto fatal para almacenamiento de contrasenas.
Rendimiento de GPU modernas:
- MD5: 180 mil millones de hashes/seg
- SHA-256: 10 mil millones de hashes/seg
- bcrypt (cost 12): 1,000 hashes/seg
Incluso una contrasena compleja de 8 caracteres puede ser crackeada en minutos cuando se almacena con SHA-256.
Razon 2: Se Requiere Gestion Manual de Salt
# ❌ Enfoque incorrecto
hash = sha256(password)
# Problema: Vulnerable a ataques de Rainbow Table
# ⚠️ Mejorado pero aun insuficiente
salt = generate_random_salt()
hash = sha256(salt + password)
# Problema: Aun demasiado rapido
Razon 3: Vulnerabilidad a Aceleracion GPU
SHA-256 es facilmente paralelizable en GPUs. Los atacantes pueden calcular hashes a velocidades tremendas con solo unas pocas GPUs de gaming.
bcrypt: 27 Anos de Estandar Probado
Como Funciona
bcrypt(cost, salt, password) → hash
cost: Numero de iteraciones de calculo (2^cost)
salt: Cadena aleatoria de 22 caracteres (autogenerada)
Por Que es bcrypt Seguro?
- Intencionalmente lento: Velocidad controlada por cost factor
- Salt automatico: Hash diferente cada vez
- Intensivo en memoria: Dificil de acelerar con GPU
Guia de Cost Factor (2026)
| Cost | Tiempo de Hash | Uso Recomendado |
|---|---|---|
| 10 | ~100ms | Desarrollo/pruebas |
| 12 | ~250ms | Apps web generales (recomendado) |
| 13-14 | ~500ms | Requisitos de alta seguridad |
| 15+ | 1seg+ | Propositos especiales |
Ejemplos de Codigo
// Node.js with bcrypt
const bcrypt = require('bcrypt');
// Hashing (registro)
const hash = await bcrypt.hash(password, 12); // cost 12
// Verificacion (login)
const isValid = await bcrypt.compare(inputPassword, storedHash);
# Python with bcrypt
import bcrypt
# Hashing
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Verificacion
is_valid = bcrypt.checkpw(input_password.encode(), stored_hash)
Argon2: El Estandar de Nueva Generacion
Que es Argon2?
Ganador de la Password Hashing Competition 2015. Es el algoritmo #1 recomendado por OWASP para 2026.
Variantes de Argon2
| Variante | Caracteristicas | Recomendacion |
|---|---|---|
| Argon2d | Resistente a ataques GPU | Vulnerable a canales laterales |
| Argon2i | Resistente a canales laterales | Vulnerable a ataques GPU |
| Argon2id | Hibrido d + i | ✅ Recomendado |
Parametros de Argon2
Argon2id(memory, iterations, parallelism, password, salt)
- memory: Uso de memoria (KB)
- iterations: Numero de iteraciones
- parallelism: Numero de hilos paralelos
Configuracion Recomendada OWASP (2026)
Configuracion minima:
- memory: 64MB (65536 KB)
- iterations: 3
- parallelism: 4
Alta seguridad:
- memory: 256MB
- iterations: 4
- parallelism: 8
Ejemplos de Codigo
// Node.js with argon2
const argon2 = require('argon2');
// Hashing
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536, // 64MB
timeCost: 3,
parallelism: 4
});
// Verificacion
const isValid = await argon2.verify(storedHash, inputPassword);
# Python with argon2-cffi
from argon2 import PasswordHasher
ph = PasswordHasher(
memory_cost=65536,
time_cost=3,
parallelism=4
)
# Hashing
hash = ph.hash(password)
# Verificacion
try:
ph.verify(stored_hash, input_password)
except VerifyMismatchError:
# Contrasena no coincide
bcrypt vs Argon2: Cual Elegir?
Tabla de Comparacion
| Item | bcrypt | Argon2id |
|---|---|---|
| Edad | 1999 (27 anos) | 2015 (11 anos) |
| Validacion | 27 anos probado en campo | Validado academicamente |
| Ajuste de memoria | ❌ | ✅ |
| Resistencia GPU | ⚠️ Media | ✅ Fuerte |
| Librerias | Todos los lenguajes | La mayoria de lenguajes |
| Ranking OWASP | #2 | #1 |
Guia de Seleccion
Elegir bcrypt:
- Necesita compatibilidad con sistemas legados
- Se prefiere estabilidad probada
- Se prefiere configuracion simple
Elegir Argon2id:
- Comenzando nuevo proyecto
- Siguiendo ultimos estandares de seguridad
- Necesita alta resistencia a GPU
Orden de Recomendacion 2026 (OWASP)
#1: Argon2id
#2: bcrypt
#3: scrypt
#4: PBKDF2 (cuando se necesita compatibilidad)
Cuando Usar SHA-256
SHA-256 es perfecto para propositos distintos a contrasenas.
Casos de Uso Adecuados
| Caso de Uso | Ejemplo |
|---|---|
| Integridad de archivos | Verificacion de descarga, confirmacion de backup |
| Firmas digitales | JWT, certificados |
| Blockchain | Mineria de Bitcoin |
| Checksums | Verificacion de transmision de datos |
| Tablas hash | (con HMAC) Almacenamiento de claves API |
Ejemplo de Codigo
// Hash de archivo (Node.js)
const crypto = require('crypto');
const fs = require('fs');
const fileBuffer = fs.readFileSync('file.zip');
const hash = crypto.createHash('sha256').update(fileBuffer).digest('hex');
console.log(hash); // "a1b2c3d4..."
Lista de Verificacion de Implementacion Practica
Almacenamiento de Contrasenas
- Usar Argon2id o bcrypt
- Establecer work factor apropiado (250-500ms)
- Usar generacion automatica de salt de la libreria
- Almacenar resultado completo del hash (incluyendo salt)
Verificacion de Contrasenas
- Usar funciones de comparacion seguras contra timing attacks
- Tiempo de respuesta consistente en fallo de verificacion
- Limitar intentos de login fallidos
Migracion
- Actualizacion gradual a nuevo hash
- Re-hashear con nuevo algoritmo en login exitoso
- Usar prefijo para identificar hashes antiguos
Preguntas Frecuentes
P1: Como manejo contrasenas existentes almacenadas con MD5?
R: Re-hashea con el nuevo algoritmo cuando los usuarios inicien sesion.
// En login exitoso
if (hash.startsWith('$md5$')) {
// Re-hashear con bcrypt
const newHash = await bcrypt.hash(inputPassword, 12);
await updateUserHash(userId, newHash);
}
P2: No es un problema el limite de 72 bytes de bcrypt?
R: La mayoria de contrasenas estan dentro de 72 bytes. Para entradas mas largas, primero hashea con SHA-256, luego aplica bcrypt.
// Manejando contrasenas largas
const prehash = crypto.createHash('sha256').update(password).digest('base64');
const finalHash = await bcrypt.hash(prehash, 12);
P3: Un cost factor alto no te hace vulnerable a ataques DoS?
R: Si. Implementa rate limiting en peticiones de login. 250-500ms es el balance apropiado.
P4: Es necesario el pepper?
R: El pepper (clave secreta a nivel de aplicacion) proporciona seguridad adicional pero no es requerido. Solo salt es suficiente.
P5: Puedo usar herramientas de hash online?
R: Usa solo para propositos de aprendizaje/prueba. En produccion, el hashing debe hacerse del lado del servidor. El Generador de Hash es seguro ya que procesa 100% del lado del cliente.
Conclusion
| Caso de Uso | Algoritmo Recomendado |
|---|---|
| Almacenamiento de contrasenas | Argon2id > bcrypt |
| Integridad de archivos | SHA-256 |
| Firmas digitales | SHA-256 / SHA-512 |
| Compatibilidad legada | bcrypt / PBKDF2 |
Principios Clave:
- Nunca usar hashes rapidos (SHA-256, MD5) para contrasenas
- bcrypt cost 12+, Argon2 memory 64MB+
- Usar generacion automatica de salt proporcionada por libreria
Herramientas Relacionadas
| Herramienta | Proposito |
|---|---|
| Hash Generator | Generar hashes SHA-256, bcrypt |
| Password Generator | Generar contrasenas fuertes |
Sobre el Autor
Toolypet Team
Development Team
The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.