Criptografia em Node.js: módulo crypto para criptografia e hash
No desenvolvimento web moderno, a segurança dos dados é um aspecto criticamente importante. O Node.js fornece o módulo interno crypto, que implementa funções criptográficas, incluindo criptografia simétrica e assimétrica, hash e também o cálculo de códigos de autenticação de mensagens (HMAC). Neste artigo, vamos detalhar os principais recursos do módulo crypto com exemplos práticos.
Instalação e importação
O módulo crypto faz parte da biblioteca padrão do Node.js, portanto, não é necessária instalação adicional. Para usá-lo, basta importá-lo:
const crypto = require('crypto');Hash de dados
Hash é uma transformação unidirecional de dados em uma string de comprimento fixo. O algoritmo mais popular é o SHA-256. Hashes são usados para verificar a integridade dos dados e armazenar senhas (em combinação com salt).
const data = "Mensagem secreta";const hash = crypto.createHash('sha256') .update(data) .digest('hex');
console.log(`Hash SHA-256: ${hash}`);// Saída: string de 64 caracteresPara aumentar a segurança das senhas, use obrigatoriamente salt e o algoritmo PBKDF2 ou bcrypt. Exemplo com PBKDF2:
const password = "senha_do_usuario";const salt = crypto.randomBytes(16).toString('hex');
crypto.pbkdf2(password, salt, 100000, 64, 'sha512', (err, derivedKey) => { if (err) throw err; console.log(`Hash da senha: ${derivedKey.toString('hex')}`); console.log(`Salt: ${salt}`);});Criptografia simétrica (AES)
A criptografia simétrica usa a mesma chave para criptografar e descriptografar. O algoritmo mais comum é o AES (Advanced Encryption Standard). Vamos ver a criptografia e descriptografia usando AES-256-CBC.
const algorithm = 'aes-256-cbc';const key = crypto.randomBytes(32); // chave de 256 bitsconst iv = crypto.randomBytes(16); // vetor de inicialização
// Criptografiafunction 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 };}
// Descriptografiafunction 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;}
// Exemplo de usoconst message = "Dados confidenciais";const encrypted = encrypt(message);console.log(`Criptografado: ${encrypted.encryptedData}`);
const decrypted = decrypt(encrypted.encryptedData, encrypted.iv);console.log(`Descriptografado: ${decrypted}`);Importante: Nunca use o mesmo IV para mensagens diferentes. Gere um novo IV aleatório para cada operação de criptografia.
Criptografia assimétrica (RSA)
A criptografia assimétrica usa um par de chaves: uma pública para criptografar e uma privada para descriptografar. O RSA é o algoritmo mais popular.
const { generateKeyPairSync, publicEncrypt, privateDecrypt } = crypto;
// Geração de chavesconst { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' }});
// Criptografia com chave públicaconst dataToEncrypt = "Mensagem secreta para RSA";const encryptedData = publicEncrypt(publicKey, Buffer.from(dataToEncrypt));console.log(`Criptografado com RSA: ${encryptedData.toString('base64')}`);
// Descriptografia com chave privadaconst decryptedData = privateDecrypt(privateKey, encryptedData);co