SHA-256 frente a SHA-3 compara el caballo de batalla de la familia SHA-2 con el estándar basado en Keccak que el NIST publicó en 2015. Ninguno está roto ni cerca de estarlo, y ambos ofrecen la misma seguridad nominal con una salida de 256 bits. Se diferencian en el diseño interno, que influye en la extensión de longitud, en la velocidad y en cómo se usan dentro de algoritmos más recientes.
De un vistazo
| SHA-256 | SHA3-256 | |
|---|---|---|
| Estándar | FIPS 180-4 (familia de 2001, revisión de 2015) | FIPS 202 (2015) |
| Construcción | Merkle–Damgård, 64 rondas de una función de compresión de 32 bits | Esponja sobre la permutación Keccak-f de 1600 bits, 24 rondas |
| Salida | 256 bits | 256 bits |
| Resistencia a colisiones / a preimágenes | 128 / 256 bits | 128 / 256 bits |
| Extensión de longitud | Sí, hash(secret ‖ m) no es un MAC | No |
| Variantes de salida extensible | Ninguna | SHAKE128, SHAKE256 |
| Rendimiento, entradas de 16 KiB, OpenSSL 3.6.5 | unos 2,85 GB/s | unos 1,01 GB/s |
| Rendimiento, entradas de 16 bytes | unos 0,17 GB/s | unos 0,07 GB/s |
| Instrucciones de CPU | Extensiones SHA de Intel y AMD, ARMv8 SHA2 | Instrucciones SHA3 de ARMv8.2 (EOR3, RAX1, XAR, BCAX) |
| Lo exigen | TLS, X.509, JOSE S256 y RS256, etc., Bitcoin, Git (repositorios SHA-256) | ML-KEM, ML-DSA (SHAKE y SHA3), los conjuntos SHAKE de SLH-DSA, Ed448 (SHAKE256) |
| Efecto cuántico | Grover: el esfuerzo para hallar una preimagen se reduce como mucho a su raíz cuadrada; sigue aprobado | Igual |
Rendimiento medido con openssl speed -evp en un núcleo de un Apple M4 Max, que acelera por hardware ambas familias.
Diseño
SHA-256 procesa el mensaje en bloques de 64 bytes y pasa cada uno a una función de compresión junto con el estado anterior de 256 bits; el estado final es el resumen. Como el resumen es todo el estado interno, cualquiera que conozca SHA-256(x) y la longitud de x puede seguir calculando el hash y obtener SHA-256(x ‖ padding ‖ y) sin conocer x. Esa extensión de longitud es inofensiva para las firmas y para HMAC, pero rompe los MAC ingenuos como SHA-256(key ‖ message).
SHA-3 es una esponja: absorbe la entrada en un estado de 1600 bits mediante la permutación Keccak-f y exprime la salida a partir de una parte de ese estado. En SHA3-256, 1088 bits del estado forman la tasa (rate) y 512 bits la capacidad, que nunca se emite, así que la extensión de longitud es imposible y SHA3-256(key ‖ message) es un MAC sólido (el NIST estandariza KMAC para ese fin). La misma esponja da lugar a las funciones de salida extensible SHAKE128 y SHAKE256, que los algoritmos poscuánticos usan para expandir semillas en matrices y ruido.
El NIST eligió Keccak en 2012 tras un concurso de cinco años que empezó cuando los ataques contra MD5 y SHA-1 despertaron temores por la estructura similar de SHA-2. Esos temores no se materializaron: los mejores ataques contra SHA-256 alcanzan unos 31 de los 64 pasos en la búsqueda de colisiones, y la función completa no muestra ninguna debilidad. Por eso SHA-3 es una salvaguarda, no un sustituto.
Velocidad
En el Apple M4 Max ambas familias tienen instrucciones propias y, aun así, SHA-256 es casi tres veces más rápido con entradas largas: unos 2,85 GB/s frente a 1,01 GB/s de SHA3-256 en OpenSSL 3.6.5, y SHA3-512 se queda en 0,53 GB/s. En las CPU x86 con extensiones SHA el panorama es parecido; en procesadores sin instrucciones de hash, SHA-3 y SHA-256 están más igualados, y BLAKE2 o BLAKE3 son más rápidos que ambos. En la mayoría de las aplicaciones cualquiera de los dos es mucho más rápido que la E/S que lo rodea; la diferencia importa al calcular el hash de archivos muy grandes, en los árboles de Merkle y en las cadenas de bloques.
SHA3-256 no es Keccak-256
Ethereum adoptó Keccak antes de que FIPS 202 fuera definitivo, y después FIPS 202 cambió el relleno (añadió bits de separación de dominio). Las dos funciones comparten la permutación, pero dan resúmenes sin ninguna relación entre sí. La función keccak256 de Solidity, el RPC web3_sha3 y todas las direcciones, selectores de función y resúmenes EIP-712 de Ethereum usan Keccak-256. Llamar al SHA3-256 de una biblioteca en código de Ethereum produce resultados erróneos sin que aparezca ningún error.
import { createHash } from "node:crypto";
import { keccak_256 } from "@noble/hashes/sha3.js";
const input = Buffer.from("abc");
console.log("SHA-256 ", createHash("sha256").update(input).digest("hex"));
console.log("SHA3-256 ", createHash("sha3-256").update(input).digest("hex"));
console.log("Keccak-256", Buffer.from(keccak_256(input)).toString("hex"));
SHA-256 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
SHA3-256 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532
Keccak-256 4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45
Los valores de SHA-256 y SHA3-256 coinciden con los ejemplos de FIPS 180-4 y FIPS 202 para «abc».
Cuándo elegir cada uno
- Interoperabilidad en los protocolos (TLS, certificados, JWT, SSH, Git, gestores de paquetes, Bitcoin): SHA-256, porque es lo que calcula la otra parte.
- Hash con clave: HMAC-SHA256 funciona con cualquier hash SHA-2; si prefieres una construcción sencilla con clave, KMAC o SHA-3 con clave evitan la doble pasada de HMAC.
- Expansión de semillas, flujos aleatorios deterministas, salida de longitud variable: SHAKE256 o SHAKE128.
- Algoritmos poscuánticos: lo que fije internamente el estándar; ML-KEM y ML-DSA usan SHA3 y SHAKE, así que las bibliotecas que los implementan ya incluyen SHA-3.
- Ethereum: Keccak-256, nunca el SHA3-256 de FIPS.
- Un segundo hash, de estructura distinta, para defensa en profundidad (por ejemplo, el doble hash de archivos de conservación a largo plazo): SHA-3 junto a SHA-256.
- Velocidad pura sin requisitos FIPS: BLAKE2 o BLAKE3 en CPU sin instrucciones de hash.
Notas de migración
Cambiar de función hash cambia todos los resúmenes, así que es un cambio de formato y no un simple cambio de biblioteca.
- Versiona el identificador: guarda el algoritmo junto a cada resumen (
sha256:,sha3-256:, multihash, un OID), como hacen los sistemas direccionados por contenido, por ejemplo los registros de contenedores y SRI. - Publica ambos durante la transición: calcula los dos resúmenes, verifica el que conozca el consumidor y retira el antiguo cuando los consumidores se hayan actualizado.
- Revisa las suposiciones sobre la extensión de longitud: si el código construye MAC como
hash(secret ‖ message), pasar a SHA-3 lo corrige, pero pasar a HMAC también lo corrige con SHA-256. - Cuidado con el truncamiento y las codificaciones: los resúmenes viajan en hex, base64 o base64url; las codificaciones que no coinciden son más habituales que los algoritmos que no coinciden.
- No migres solo por motivos cuánticos: incluso con el algoritmo de Grover, ambas funciones conservan al menos 128 bits de resistencia a preimágenes, y el borrador del plan de transición del NIST mantiene las dos en servicio.