Hashes de strings en Node.js: createHash, Web Crypto y el aviso de bcrypt
Node.js te da dos formas de hashear un string y un aviso que conviene grabarse: SHA es rápido y perfecto para checksums, pésimo para contraseñas. Elige `crypto.createHash` si vas con la API clásica o `crypto.subtle.digest` para código que también corre en navegador.
createHash es la API canónica de Node
crypto.createHash lleva en Node desde la 0.x y es lo que usan casi todos los snippets que encuentras por la web. Es síncrona, rápida y cubre cualquier algoritmo que exponga OpenSSL (SHA-256, SHA-512, SHA-1, MD5 y los exóticos vía getHashes()).
```js import { createHash } from "node:crypto";
const digest = createHash("sha256") .update("AldeaCode", "utf8") .digest("hex"); ```
Pasa siempre el encoding explícito en update. El default depende de cómo el motor interprete el buffer, y eso muerde la primera vez que alguien mete un string con acentos. utf8 es lo que quieres el 99% del tiempo.
Web Crypto es la opción portable
Desde Node 19, globalThis.crypto es la misma Web Crypto API que tienes en el navegador. Es asíncrona, devuelve un ArrayBuffer y te deja enviar el mismo código a un navegador, un Cloudflare Worker y un servidor Node sin tocar nada.
const bytes = new TextEncoder().encode("AldeaCode");
const buffer = await crypto.subtle.digest("SHA-256", bytes);
const hex = [...new Uint8Array(buffer)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
La Web Crypto API solo soporta SHA-1, SHA-256, SHA-384 y SHA-512. Si necesitas SHA-3 o BLAKE te quedas en createHash. Para todo lo demás, la API portable ya es el mejor default.
Nunca hashes contraseñas con SHA
Esta es la regla que sigue pillando a gente en producción. SHA-256 de una contraseña no es una contraseña hasheada. Es una línea de GPU. Una tarjeta moderna prueba miles de millones de candidatos SHA-256 por segundo, así que cualquier password de menos de 14 caracteres aleatorios cae en minutos.
Para contraseñas usa bcrypt, scrypt o Argon2id. Node trae scrypt nativo en crypto.scrypt. Para bcrypt o Argon2 instala bcrypt o argon2 desde npm. Son lentas a propósito: el factor de coste se ajusta para que el hash tarde 100 ms hoy y siga siendo caro para un atacante.
SHA es para checksums, content addressing, ETags, claves HMAC e integridad. Otro problema, otra herramienta.
Streams para archivos grandes
Si vas a hashear un upload de vídeo de 4 GB, no lo cargues en memoria. createHash es un stream y se conecta a una pipe sin quejarse:
```js import { createReadStream } from "node:fs"; import { createHash } from "node:crypto";
const hash = createHash("sha256"); createReadStream("./video.mp4").pipe(hash).on("finish", () => { console.log(hash.digest("hex")); }); ```
La Web Crypto API no tiene equivalente streaming. Si necesitas hashear archivos de varios gigas en un codebase portable, vuelves a createHash quieras o no.
Ejemplo completo
javascriptimport { createHash } from "node:crypto";
// Síncrono, Node clásico
const sha256 = createHash("sha256")
.update("AldeaCode", "utf8")
.digest("hex");
console.log(sha256);
// Asíncrono, portable a navegadores y edge runtimes
const bytes = new TextEncoder().encode("AldeaCode");
const buffer = await crypto.subtle.digest("SHA-256", bytes);
const hex = [...new Uint8Array(buffer)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
console.log(hex); ¿Solo necesitas el resultado?
Cuando solo necesitas hashear un string para una comprobación puntual, tipo comparar un checksum que te ha mandado un proveedor por mail, abrir un REPL de Node sobra. Pega el string en el generador de hashes en el navegador, mira SHA-1, SHA-256, SHA-384 y SHA-512 a la vez, y no sales de la pestaña.
Abrir Generador de Hashes SHA →Preguntas frecuentes
¿Es seguro usar createHash en 2026?
Sí para SHA-256 y SHA-512. La API es estable y cumple FIPS 180-4. Evita MD5 y SHA-1 en cualquier integridad nueva; los dos tienen ataques de colisión prácticos.
¿Necesito await en crypto.subtle.digest?
Sí. Web Crypto es totalmente async y devuelve una Promise que resuelve a un ArrayBuffer. Si te olvidas del await te queda un objeto Promise en lugar de los bytes.
¿Qué hash es el más rápido en Node?
SHA-256 acelerado por hardware gana en x86 con SHA-NI. createHash es más rápido que crypto.subtle en bucles síncronos cerrados porque no hay overhead de Promise. Los dos van sobrados para payloads normales.