tutoriales·8 min read

MD5 vs SHA-256: por qué sigue existiendo un generador MD5 "roto"

Descubre por qué MD5 está criptográficamente roto para contraseñas pero sigue siendo válido para checksums de integridad, y cuándo usar cada uno.

DevToolsHub Team
·
MD5 vs SHA-256: por qué sigue existiendo un generador MD5 "roto"

La paradoja de MD5: roto pero indispensable

Si lees cualquier blog de seguridad moderno, el mensaje es claro: "MD5 está roto, no lo uses". Y es verdad. MD5 fue roto criptográficamente en 2004 cuando investigadores chinos demostraron que podían crear colisiones a voluntad. Desde entonces, ha sido considerado inseguro para cualquier propósito criptográfico serio.

Pero si MD5 está tan roto, ¿por qué nuestra herramienta de MD5 sigue ahí? ¿Por qué prácticamente todos los sistemas operativos siguen incluyendo utilidades MD5? ¿Por qué cuando descargas un archivo grande de Linux, a veces el checksum viene en MD5?

La respuesta es simple: MD5 sigue siendo útil, pero no para lo que crees. La confusión viene de mezclar dos conceptos completamente diferentes: integridad de datos y seguridad criptográfica. Son lo mismo en teoría, pero en la práctica tienen requisitos muy distintos.


Integridad vs Seguridad: la distinción que salva proyectos

Cuando alguien dice "MD5 está roto", generalmente se refiere a que ya no es seguro para:

  • Almacenar contraseñas (hash de passwords)
  • Firmar documentos (firmas digitales)
  • Autenticar mensajes (HMAC en sistemas críticos)

En estos casos, un atacante podría crear dos documentos diferentes con el mismo hash MD5, lo que rompe la confianza en el sistema. Si firmas un contrato con MD5, alguien podría crear otro contrato con términos completamente diferentes pero el mismo hash, y tu firma seguiría siendo "válida".

Pero para verificar integridad de archivos, MD5 sigue siendo perfectamente adecuado. ¿Por qué? Porque el escenario de ataque es completamente diferente.

Imagina que descargas una ISO de Ubuntu de 4GB. Quieres verificar que no se corrompió durante la descarga. El sitio oficial te da un checksum MD5. ¿Puede un atacante aprovecharse de que MD5 tiene colisiones? No, porque:

  1. El atacante no controla el archivo original: Ubuntu generó el checksum de su ISO. El atacante no puede cambiar la ISO original sin que el checksum cambie.
  2. El atacante no controla el checksum: El checksum está en el servidor de Ubuntu, firmado con su clave GPG. El atacante no puede cambiarlo.
  3. La colisión requiere crear dos archivos nuevos: Para que una colisión MD5 sea útil, el atacante necesitaría crear una ISO maliciosa que tenga el mismo hash que la ISO original de Ubuntu. Eso es computacionalmente inviable, incluso con MD5 roto.

Las colisiones MD5 demostradas requieren que el atacante controle ambos archivos desde el principio. En el escenario de descarga de archivos, el atacante solo controla uno (el archivo que intenta inyectar), y el otro (el archivo original) es inmutable.


El caso real: cuando MD5 sí es peligroso

Para entender por qué MD5 es seguro para checksums pero peligroso para contraseñas, veamos el escenario donde MD5 falla.

Escenario 1: Contraseñas (MD5 es peligroso)

Tienes una base de datos de usuarios con contraseñas hasheadas con MD5:

usuario1@example.com: 5f4dcc3b5aa765d61d8327deb882cf99  # "password"
usuario2@example.com: 5f4dcc3b5aa765d61d8327deb882cf99  # "password"

Problema 1: Dos usuarios con la misma contraseña tienen el mismo hash. Sin salt, las tablas rainbow funcionan perfectamente.

Problema 2: MD5 es rápido. Una GPU moderna puede calcular billones de hashes MD5 por segundo. Un atacante con una tabla de las 10 millones de contraseñas más comunes puede romper tu base de datos en minutos.

Problema 3: Colisiones precomputadas. Existen bases de datos con millones de colisiones MD5 precalculadas. Un atacante no necesita calcular nada, solo buscar.

Escenario 2: Checksums de archivos (MD5 es aceptable)

Descargas un archivo de 4GB y quieres verificar que llegó completo:

$ md5sum archivo-grande.zip
d41d8cd98f00b204e9800998ecf8427e  archivo-grande.zip

El sitio oficial dice que el checksum correcto es d41d8cd98f00b204e9800998ecf8427e. ¿Coincide? Sí. El archivo está íntegro.

¿Puede un atacante crear un archivo malicioso con el mismo checksum? Teóricamente sí, con suficiente poder computacional. Pero prácticamente no, porque:

  • El atacante no conoce el archivo original (está en el servidor seguro)
  • El atacante tendría que crear un archivo que coincida con un hash específico preexistente
  • Incluso con MD5 roto, esto requiere más poder computacional del que cualquier atacante individual tiene

La diferencia clave: en contraseñas, el atacante controla la entrada (puede probar millones de contraseñas). En checksums, el atacante no controla la entrada (el archivo original es fijo).


Cuándo usar MD5 (y cuándo no)

✅ Usa MD5 para:

Verificar integridad de descargas

# Verificar que un archivo descargado no se corrompió
md5sum archivo-descargado.zip
# Comparar con el checksum oficial del sitio

Nuestra herramienta de MD5 es perfecta para esto. Pegas el contenido del archivo, obtienes el hash, comparas con el oficial.

Detectar duplicados en sistemas no críticos

Si tienes un sistema de almacenamiento de archivos y quieres detectar duplicados para ahorrar espacio, MD5 es rápido y suficiente:

import { createHash } from 'crypto';

function getFileHash(filePath) {
  const hash = createHash('md5');
  const file = fs.readFileSync(filePath);
  hash.update(file);
  return hash.digest('hex');
}

// Usar para detectar duplicados
const hash1 = getFileHash('archivo1.pdf');
const hash2 = getFileHash('archivo2.pdf');
if (hash1 === hash2) {
  console.log('Son el mismo archivo');
}

Cache invalidation en sistemas no críticos

Si tienes un sistema de cache y quieres saber si un archivo cambió, MD5 es rápido y funciona:

const cacheKey = `file:${md5(filePath)}`;
const cached = cache.get(cacheKey);
if (!cached) {
  const content = fs.readFileSync(filePath);
  cache.set(cacheKey, content);
}

❌ NO uses MD5 para:

Almacenar contraseñas

Nunca, nunca, nunca. Usa bcrypt, Argon2, o al menos PBKDF2 con SHA-256 (como explicamos en nuestro tutorial de SHA-256 con PBKDF2).

Firmar documentos o contratos

Usa SHA-256 o SHA-3 con firmas digitales RSA/ECDSA. MD5 es vulnerable a colisiones que podrían permitir falsificar firmas.

Tokens de autenticación o sesiones

Usa HMAC con SHA-256 o tokens JWT firmados con algoritmos modernos.

Cualquier sistema donde un atacante pueda controlar ambas entradas

Si el atacante puede crear tanto el archivo original como el archivo malicioso, MD5 es inseguro.


SHA-256: cuando la seguridad importa

SHA-256 es el sucesor moderno de MD5. Es parte de la familia SHA-2, diseñada por la NSA y estandarizada por NIST. A diferencia de MD5, SHA-256 no tiene colisiones prácticas conocidas.

Ventajas de SHA-256:

  • Sin colisiones conocidas: A pesar de años de análisis criptográfico intensivo, nadie ha demostrado una colisión práctica
  • Salida más larga: 256 bits vs 128 bits de MD5, lo que hace las colisiones teóricamente imposibles con la tecnología actual
  • Mejor resistencia a preimagen: Es computacionalmente inviable encontrar un input que produzca un hash específico

Desventajas de SHA-256:

  • Más lento: SHA-256 es más lento que MD5, lo que importa en sistemas que procesan millones de hashes por segundo
  • Overkill para checksums: Para verificar que un archivo no se corrompió, MD5 es suficiente

Nuestra herramienta de SHA-256 es ideal para cuando necesitas seguridad real, no solo integridad.


Ejemplo práctico: sistema de archivos con doble hash

En muchos sistemas reales, uso ambos: MD5 para operaciones rápidas, SHA-256 para verificación crítica.

import { createHash } from 'crypto';

class FileStorage {
  constructor() {
    this.files = new Map();
  }

  // Guardar archivo - usar MD5 para detección rápida de duplicados
  saveFile(content) {
    const md5Hash = createHash('md5').update(content).digest('hex');
    
    if (this.files.has(md5Hash)) {
      return { duplicate: true, id: md5Hash };
    }
    
    // Para archivos críticos, también guardar SHA-256
    const sha256Hash = createHash('sha256').update(content).digest('hex');
    
    this.files.set(md5Hash, {
      content,
      md5: md5Hash,
      sha256: sha256Hash,
      createdAt: Date.now()
    });
    
    return { duplicate: false, id: md5Hash };
  }

  // Verificar integridad - usar MD5 (rápido)
  verifyIntegrity(id, content) {
    const file = this.files.get(id);
    if (!file) return { valid: false, reason: 'not_found' };
    
    const md5Hash = createHash('md5').update(content).digest('hex');
    if (md5Hash !== file.md5) {
      return { valid: false, reason: 'corrupted' };
    }
    
    return { valid: true };
  }

  // Verificación crítica - usar SHA-256 (seguro)
  criticalVerify(id, content) {
    const file = this.files.get(id);
    if (!file) return { valid: false, reason: 'not_found' };
    
    const sha256Hash = createHash('sha256').update(content).digest('hex');
    if (sha256Hash !== file.sha256) {
      return { valid: false, reason: 'tampered' };
    }
    
    return { valid: true };
  }
}

Este patrón es común en sistemas de almacenamiento distribuido: MD5 para operaciones diarias (detección de duplicados, cache), SHA-256 para verificaciones críticas (auditoría, forense).


El futuro: SHA-3 y BLAKE2

Aunque SHA-256 es el estándar actual, hay alternativas más modernas:

SHA-3 (Keccak): Ganador del concurso de hash functions de NIST en 2015. Diseñado desde cero para ser resistente a ataques que afectaron a SHA-1 y SHA-2.

BLAKE2: Más rápido que MD5 pero más seguro que SHA-256. Es el algoritmo usado por sistemas modernos como WireGuard y algunos sistemas de archivos.

Sin embargo, para la mayoría de casos prácticos, SHA-256 sigue siendo el equilibrio correcto entre seguridad y rendimiento.


Resumen: la regla de oro

La regla simple que uso en todos mis proyectos:

  • Si un atacante puede controlar la entrada: Usa SHA-256 o mejor
  • Si el atacante no puede controlar la entrada: MD5 es suficiente
  • Si estás dudando: Usa SHA-256. El overhead es mínimo en la mayoría de casos

Nuestra herramienta de MD5 existe porque MD5 sigue siendo útil para su propósito original: verificar integridad de datos cuando el atacante no controla ambos lados de la ecuación. Pero para cualquier cosa relacionada con seguridad, autenticación o criptografía, usa SHA-256 con PBKDF2, bcrypt, o Argon2.

La próxima vez que alguien diga "MD5 está roto, bórralo", pregúntate: ¿para qué lo estás usando? La respuesta importa más que el algoritmo.

#md5#checksums#integridad#hashing#seguridad

Related articles