Cryptography in Node.js: encryption and hashing using the crypto module
Data security is one of the key aspects of modern web development. In Node.js, the built-in crypto module provides powerful tools for cryptographic protection: from password hashing to asymmetric encryption. In this article, we will thoroughly examine the main functions of the crypto module, learn how to encrypt and decrypt data, and also securely store passwords using hashing.
1. Importing the crypto module
The crypto module is built-in, so it does not require installing additional packages. It is imported in the standard way:
const crypto = require('crypto');2. Hashing data
Hashing is the process of converting data of arbitrary length into a fixed-length string. Unlike encryption, a hash function is irreversible. The most popular algorithms are SHA-256, SHA-512.
Example: hashing a string using SHA-256
const data = 'PythonLib — ваш путеводитель в мир IT';const hash = crypto.createHash('sha256').update(data).digest('hex');console.log('SHA-256 hash:', hash);Example: hashing with salt (bcrypt)
For secure password storage, it is recommended to use the bcrypt or scrypt algorithm. Node.js has built-in support for scrypt:
const password = 'mySuperPassword123';const salt = crypto.randomBytes(16).toString('hex');
crypto.scrypt(password, salt, 64, (err, derivedKey) => { if (err) throw err; console.log('Password hash:', derivedKey.toString('hex'));});3. Symmetric encryption (AES)
Symmetric encryption uses the same key for encrypting and decrypting data. The most common algorithm is AES (Advanced Encryption Standard).
Encrypting data with AES-256-CBC
const algorithm = 'aes-256-cbc';const key = crypto.randomBytes(32); // 256-bit keyconst iv = crypto.randomBytes(16); // initialization vector
function 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 };}
const originalText = 'Секретные данные для PythonLib';const encrypted = encrypt(originalText);console.log('Encrypted data:', encrypted);Decrypting data
function decrypt(encryptedObj) { const decipher = crypto.createDecipheriv( algorithm, key, Buffer.from(encryptedObj.iv, 'hex') ); let decrypted = decipher.update(encryptedObj.encryptedData, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted;}
const decryptedText = decrypt(encrypted);console.log('Decrypted text:', decryptedText);4. Asymmetric encryption (RSA)
Asymmetric encryption uses a pair of keys: a public key and a private key. Data is encrypted with the public key and decrypted with the private key. This is the foundation of HTTPS and digital signatures.
Generating an RSA key pair
const { generateKeyPairSync } = require('crypto');
const { publicKey, privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' }});
console.log('Public key:', publicKey);console.log('Private key:', privateKey);Encryption and decryption with RSA
const secretMessage = 'Привет, PythonLib!';
// Encryption with public keyconst encryptedData = crypto.publicEncrypt( { key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }, Buffer.from(secretMessage));console.log('Encrypted Also in library
Elasticsearch client for Kotlin: integration, examples, and capabilities
Task Queues in C# (.NET): System.Threading.Channels, Hangfire, and RabbitMQ
Task Queues in Java: ExecutorService and ThreadPoolExecutor