Criptografía en Node.js: módulo crypto para cifrado y hash
En el desarrollo web moderno, la seguridad de los datos es un aspecto crítico. Node.js proporciona el módulo integrado crypto, que implementa funciones criptográficas, incluyendo cifrado simétrico y asimétrico, hash, así como el cálculo de códigos de autenticación de mensajes (HMAC). En este artículo, analizaremos en detalle las principales capacidades del módulo crypto con ejemplos prácticos.
Instalación y configuración
El módulo crypto es parte de la biblioteca estándar de Node.js, por lo que no se requiere instalación adicional. Para usarlo, basta con importarlo:
const crypto = require('crypto');Hash de datos
El hash es una transformación unidireccional de datos en una cadena de longitud fija. El algoritmo más popular es SHA-256. Los hash se utilizan para verificar la integridad de los datos y almacenar contraseñas (en combinación con sal).
const data = "Mensaje secreto";const hash = crypto.createHash('sha256') .update(data) .digest('hex');
console.log(`Hash SHA-256: ${hash}`);// Salida: cadena de 64 caracteresPara mejorar la seguridad de las contraseñas, use siempre sal (salt) y el algoritmo PBKDF2 o bcrypt. Ejemplo con PBKDF2:
const password = "contraseña_usuario";const salt = crypto.randomBytes(16).toString('hex');
crypto.pbkdf2(password, salt, 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; console.log(`Hash de contraseña: ${derivedKey.toString('hex')}`); console.log(`Sal: ${salt}`);});Cifrado simétrico (AES)
El cifrado simétrico utiliza la misma clave para cifrar y descifrar. El algoritmo más común es AES (Advanced Encryption Standard). Veamos el cifrado y descifrado usando AES-256-CBC.
const algorithm = 'aes-256-cbc';const key = crypto.randomBytes(32); // Clave de 256 bitsconst iv = crypto.randomBytes(16); // Vector de inicialización
// Cifradofunction encrypt(text) { const cipher = crypto.createCipheriv(algorithm, key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { iv: iv.toString('hex'), encryptedData: encrypted };}
// Descifradofunction decrypt(encryptedData, ivHex) { const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(ivHex, 'hex')); let decrypted = decipher.update(encryptedData, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted;}
// Ejemplo de usoconst message = "Datos confidenciales";const encrypted = encrypt(message);console.log(`Cifrado: ${encrypted.encryptedData}`);
const decrypted = decrypt(encrypted.encryptedData, encrypted.iv);console.log(`Descifrado: ${decrypted}`);Importante: Nunca use el mismo IV para diferentes mensajes. Genere un nuevo IV aleatorio para cada operación de cifrado.
Cifrado asimétrico (RSA)
El cifrado asimétrico utiliza un par de claves: una pública para cifrar y una privada para descifrar. RSA es el algoritmo más popular.
const { generateKeyPairSync, publicEncrypt, privateDecrypt } = crypto;
// Generación de clavesconst { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' }});
// Cifrado con clave públicaconst dataToEncrypt = "Mensaje secreto para RSA";const encryptedData = publicEncrypt(publicKey, Buffer.from(dataToEncrypt));console.log(`Cifrado RSA: ${encryptedData.toString('base64')}`);
// Descifrado con clave privadaconst decryptedData = privateDecrypt(privateKey, encryptedData);co También en la biblioteca
Cliente HTTP para Kotlin: Las mejores bibliotecas para trabajar con la red
Biblioteca estándar de Go (Golang): guía completa
Colas de tareas en Rust: Revisión de bibliotecas para procesamiento asíncrono
Migraciones de bases de datos en Kotlin: Resumen de herramientas y enfoques