MD5 vs SHA-1 vs SHA-256: ¿qué hash conviene usar?

Use SHA-256 para todo lo que tenga que ver con seguridad; MD5 y SHA-1 solo son aceptables cuando nadie gana nada falsificando un hash que coincida.

MD5, SHA-1 y SHA-256 hacen el mismo trabajo: convierten una entrada de cualquier longitud en una huella corta y de tamaño fijo llamada resumen o digest. La misma entrada produce siempre el mismo resumen, y cambiar un solo bit cambia el resultado entero. Los tres se diferencian en la longitud del resumen, en la velocidad y, sobre todo, en si alguien puede fabricar a propósito dos entradas distintas con el mismo resumen. Con MD5 y SHA-1 eso ya se ha hecho públicamente. Con SHA-256, no.

Los tres algoritmos de un vistazo

MD5SHA-1SHA-256
Tamaño del resumen128 bits, 32 caracteres hexadecimales160 bits, 40 caracteres hexadecimales256 bits, 64 caracteres hexadecimales
Publicación1992 (RFC 1321)1995 (FIPS 180-1)2001, como parte de la familia SHA-2
ColisionesPrácticas desde 2004Prácticas desde 2017Ningún ataque conocido
Encontrar una entrada para un resumen dadoNingún ataque prácticoNingún ataque prácticoNingún ataque práctico
Uso adecuado hoyChecksums sin fines de seguridad, claves de cachéSolo compatibilidad con sistemas antiguosLa opción por defecto para cualquier proyecto nuevo

Estos son los resúmenes completos de los cinco bytes hello, tal como los imprimen md5sum, sha1sum y sha256sum. El generador de hash muestra los mismos valores uno junto a otro, además de SHA-384 y SHA-512, tanto para texto como para un archivo de hasta 50 MB.

MD5      5d41402abc4b2a76b9719d911017c592
SHA-1    aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
SHA-256  2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Qué aportan los bits de más

La longitud del resumen fija el coste de un ataque genérico, es decir, uno que trata la función como una caja negra. Por la paradoja del cumpleaños, encontrar dos entradas cualesquiera que colisionen exige unos 2^(n/2) intentos para un resumen de n bits: 2^64 en MD5, 2^80 en SHA-1 y 2^128 en SHA-256. Encontrar una entrada que coincida con un resumen concreto (una preimagen) exige unos 2^n.

Esas cifras solo valen mientras el diseño no tenga atajos. Tanto MD5 como SHA-1 tienen atajos para encontrar colisiones, y por eso su longitud ya no cuenta toda la historia. SHA-256 no tiene ningún atajo conocido, y 2^128 queda muy lejos de cualquier capacidad de cómputo que exista.

Cómo se rompieron MD5 y SHA-1

Un ataque de colisión no permite a nadie invertir un hash. Lo que permite es preparar de antemano dos entradas distintas que comparten resumen, conseguir que una de ellas sea aceptada como fiable y después sustituirla por la otra. La variante peligrosa es la colisión de prefijo elegido (chosen-prefix): el atacante escoge dos comienzos con sentido, por ejemplo dos certificados con nombres distintos, y calcula bytes adicionales que igualan los resúmenes.

  • MD5, 2004: Xiaoyun Wang y sus colaboradores publicaron colisiones prácticas de MD5.
  • MD5, 2008: un equipo de investigadores usó una colisión de MD5 con prefijo elegido para crear un certificado de autoridad de certificación falso en el que los navegadores habrían confiado, porque una CA comercial seguía firmando certificados con MD5.
  • MD5, 2012: el malware Flame usó una colisión de MD5 para falsificar un certificado de firma de código de Microsoft.
  • SHA-1, 2017: Google y el CWI de Ámsterdam anunciaron SHAttered, dos archivos PDF distintos con el mismo resumen SHA-1. El equipo informó de unos 6500 años de CPU y 110 años de GPU de cómputo.
  • SHA-1, 2020: Gaëtan Leurent y Thomas Peyrin publicaron una colisión práctica de SHA-1 con prefijo elegido y la usaron para suplantar una clave PGP.

Los navegadores dejaron de aceptar certificados TLS con SHA-1 en 2017, y el NIST anunció en diciembre de 2022 que SHA-1 debe retirarse por completo antes de que termine 2030. Ni MD5 ni SHA-1 tienen un ataque de preimagen práctico: a partir de un resumen, nadie puede encontrar una entrada que lo produzca. Por eso los dos siguen sirviendo para detectar daños accidentales.

Velocidad: medida, no supuesta

A MD5 se le suele describir como el rápido. Calculamos el hash de los mismos 256 MB de datos aleatorios con Node 24 (OpenSSL 3.5) en un mismo ordenador de escritorio, con tres ejecuciones por algoritmo:

AlgoritmoRendimiento en esa máquina
SHA-1unos 1000 MB/s
MD5unos 730 MB/s
SHA-512unos 690 MB/s
SHA-256unos 460 MB/s

El orden depende del procesador. Esta CPU no tiene las extensiones del juego de instrucciones SHA; los procesadores que sí las tienen aceleran SHA-1 y SHA-256 por hardware, y entonces SHA-256 puede superar a MD5. SHA-512 ganó aquí a SHA-256 porque trabaja con palabras de 64 bits. Con entradas cortas la diferencia desaparece: un millón de hashes de una dirección de correo corta tardó entre 1,8 y 2,1 segundos con MD5, con SHA-1 y con SHA-256, porque el coste fijo de cada llamada pesa más que el propio cálculo. La velocidad casi nunca es un motivo real para elegir MD5.

Para qué sigue sirviendo cada uno

  • MD5: detectar corrupción accidental, eliminar duplicados entre sus propios archivos, claves de caché y ETags, y comunicarse con sistemas antiguos que lo esperan. Nunca para firmas, certificados ni comprobaciones de integridad en las que un atacante pueda aportar el archivo.
  • SHA-1: sistemas existentes que todavía no puede cambiar. Git lleva mucho tiempo nombrando los objetos con SHA-1, mediante una implementación reforzada que detecta los ataques de colisión conocidos, y también admite repositorios que usan SHA-256. HMAC-SHA1, el algoritmo por defecto detrás de los códigos TOTP de las apps de autenticación, no se ve afectado por los ataques de colisión.
  • SHA-256: checksums de descargas, firmas digitales, certificados, HMAC, direccionamiento por contenido y cualquier cosa nueva. Use SHA-256 cuando un checksum tenga que resistir manipulaciones, y reserve MD5 para los valores heredados con los que todavía tenga que coincidir.

¿Va a comprobar una descarga? El comprobador de checksum de archivos calcula el hash del archivo en su propio equipo y le indica con qué algoritmo coincide el checksum que pegue.

Ninguno sirve para guardar contraseñas

Los tres están diseñados para ser rápidos, y la rapidez es justo lo que quiere un atacante que prueba miles de millones de contraseñas. Una sal (salt) frena las tablas precalculadas, pero no ralentiza los intentos. Para almacenar contraseñas hace falta una función deliberadamente lenta y, a ser posible, que consuma mucha memoria (memory-hard). En la misma máquina que antes:

Función y parámetrosTiempo por contraseña
SHA-256, una llamada desde Nodeunos 2,5 microsegundos
Argon2id, 19 MiB de memoria, 2 iteraciones, 1 carrilunos 33 milisegundos
PBKDF2-HMAC-SHA256, 600 000 iteracionesunos 270 milisegundos
scrypt, N=2^17, r=8, p=1unos 310 milisegundos

Esos parámetros son los mínimos de la OWASP Password Storage Cheat Sheet, que recomienda Argon2id en primer lugar, después scrypt, bcrypt con un factor de trabajo de 10 o más para sistemas heredados, y PBKDF2 cuando se exige cumplir FIPS-140. Use la API de hash de contraseñas de su framework en lugar de montar una a partir de un hash simple.

HMAC: cuando un hash necesita una clave

Para demostrar que un mensaje viene de alguien que conoce un secreto, no calcule sha256(secret + message). MD5, SHA-1 y SHA-256 son vulnerables a la extensión de longitud (length extension): conocer el resumen de un mensaje permite a un atacante calcular un resumen válido para ese mismo mensaje con datos añadidos al final, sin conocer el secreto. HMAC (RFC 2104) lo evita. HMAC-SHA256 es la opción estándar, y todas estas líneas imprimen el mismo valor:

// Node.js
crypto.createHmac('sha256', 'secret').update('hello').digest('hex')

# Python
hmac.new(b'secret', b'hello', hashlib.sha256).hexdigest()

// PHP
hash_hmac('sha256', 'hello', 'secret')

// 88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b

Compare los HMAC con una función de tiempo constante, como crypto.timingSafeEqual, hmac.compare_digest o hash_equals, y no con ==.

Calcular hashes en la línea de comandos y en código

Estos son los comandos equivalentes en Linux, macOS, Windows PowerShell y cualquier sistema con OpenSSL. En PowerShell, SHA256 es el algoritmo por defecto. La última parte muestra por qué el hash de una cadena cambia según se use printf o echo: printf no añade salto de línea y echo sí.

# Linux (coreutils)
md5sum file.iso
sha1sum file.iso
sha256sum file.iso

# macOS
md5 file.iso
shasum -a 1 file.iso
shasum -a 256 file.iso

# Windows PowerShell
Get-FileHash file.iso -Algorithm MD5
Get-FileHash file.iso -Algorithm SHA1
Get-FileHash file.iso              # SHA256 is the default

# Any system with OpenSSL
openssl dgst -sha256 file.iso

# Hashing a string: printf adds no newline, echo does
printf '%s' hello | sha256sum      # 2cf24dba5fb0a30e...
echo hello | sha256sum             # 5891b5b522d5df08...

En el navegador, crypto.subtle.digest() admite SHA-1, SHA-256, SHA-384 y SHA-512, pero no MD5; si se le pide MD5, lanza un NotSupportedError. Por eso las herramientas que funcionan en el navegador, incluidas las de este sitio, calculan MD5 con una implementación aparte en JavaScript.

Preguntas Frecuentes

¿SHA-256 es más lento que MD5?

Depende del procesador. En un procesador sin extensiones SHA medimos unos 730 MB/s con MD5 y 460 MB/s con SHA-256. Los procesadores con extensiones SHA aceleran SHA-256 lo suficiente como para que pueda ser más rápido que MD5, y con cadenas cortas la diferencia es insignificante.

¿MD5 sigue valiendo para checksums de archivos?

Para detectar corrupción accidental, sí, porque nadie puede encontrar un archivo que coincida con un MD5 dado. No vale cuando un atacante ha podido preparar el archivo, porque las colisiones de MD5 son baratas. Use SHA-256 cuando el checksum tenga que resistir manipulaciones.

¿SHA-1 está roto?

Su resistencia a colisiones, sí. En 2017 se demostraron colisiones prácticas y en 2020 colisiones con prefijo elegido, así que SHA-1 no debe usarse para firmas ni certificados. HMAC-SHA1 y la resistencia a preimágenes no se ven afectados por estos ataques, pero los diseños nuevos deben usar SHA-256.

¿Qué hash debo usar para las contraseñas?

Ninguno de estos tres. Use Argon2id, o scrypt o bcrypt si Argon2id no está disponible. Son deliberadamente lentos y usan sal, lo que encarece muchísimo adivinar contraseñas a partir de una base de datos robada.