Data Encryption and Hashing in Node.js

Introduction to Data Encryption and Hashing Data security is a key aspect of application development, especially when sensitive information is involved. Encryption and hashing are two widely used techniques for securing data in transit and at rest. This chapter will explore the concepts of data encryption and hashing in the context of Node.js, diving into how these techniques work, their differences, and how to implement them in real-world applications.

Encryption: Understanding the Basics

What is Encryption?

Encryption is the process of converting plaintext into ciphertext using a cryptographic algorithm. This ensures that even if someone intercepts the data, they cannot understand it without the decryption key.

Types of Encryption:

  • Symmetric Encryption: The same key is used for both encryption and decryption.
  • Asymmetric Encryption: A pair of keys (public and private) is used, where the public key encrypts the data and the private key decrypts it.

Use Cases of Encryption:

  • Securing passwords and user data
  • Protecting communications over the internet (SSL/TLS)
  • Encrypting files and databases

Symmetric Encryption in Node.js

Symmetric encryption in Node.js can be easily implemented using the built-in crypto module. One of the most widely used algorithms is AES (Advanced Encryption Standard).

Example: Encrypting and Decrypting Data with AES

				
					const crypto = require('crypto');
const algorithm = 'aes-256-cbc'; 
const key = crypto.randomBytes(32); // Generate a secure random key
const iv = crypto.randomBytes(16);  // Initialization vector

// Encrypt function
function encrypt(text) {
    const cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
    let encrypted = cipher.update(text);
    encrypted = Buffer.concat([encrypted, cipher.final()]);
    return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
}

// Decrypt function
function decrypt(text) {
    const iv = Buffer.from(text.iv, 'hex');
    const encryptedText = Buffer.from(text.encryptedData, 'hex');
    const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv);
    let decrypted = decipher.update(encryptedText);
    decrypted = Buffer.concat([decrypted, decipher.final()]);
    return decrypted.toString();
}

// Usage
const encrypted = encrypt('Hello, World!');
console.log('Encrypted:', encrypted);
console.log('Decrypted:', decrypt(encrypted));

				
			

Explanation:

  • aes-256-cbc is the AES algorithm using a 256-bit key.
  • The crypto.createCipheriv and crypto.createDecipheriv methods handle encryption and decryption.
  • The encryption key is generated using crypto.randomBytes.

Asymmetric Encryption in Node.js

Asymmetric encryption uses two keys: a public key for encryption and a private key for decryption. RSA is a common algorithm used for this purpose.

Example: Using RSA for Encryption and Decryption

				
					const { generateKeyPairSync, publicEncrypt, privateDecrypt } = require('crypto');

// Generate RSA key pair
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
});

// Encrypt with public key
function encryptWithPublicKey(publicKey, message) {
    return publicEncrypt(publicKey, Buffer.from(message));
}

// Decrypt with private key
function decryptWithPrivateKey(privateKey, encryptedMessage) {
    return privateDecrypt(privateKey, encryptedMessage).toString();
}

// Usage
const encryptedMessage = encryptWithPublicKey(publicKey, 'Hello RSA');
console.log('Encrypted with RSA:', encryptedMessage.toString('hex'));

const decryptedMessage = decryptWithPrivateKey(privateKey, encryptedMessage);
console.log('Decrypted with RSA:', decryptedMessage);

				
			

Explanation:

  • We generate an RSA key pair using generateKeyPairSync.
  • Data is encrypted with the public key using publicEncrypt and decrypted with the private key using privateDecrypt.

Hashing: Securing Data with Integrity

What is Hashing?

Hashing is the process of converting a message or data into a fixed-length hash value using algorithms such as SHA-256. Unlike encryption, hashing is a one-way process, making it ideal for verifying data integrity.

Example: Hashing with SHA-256

				
					const crypto = require('crypto');

// Hash function
function hash(data) {
    return crypto.createHash('sha256').update(data).digest('hex');
}

// Usage
const hashedData = hash('Hello, World!');
console.log('Hashed:', hashedData);

				
			

Explanation:

  • We use crypto.createHash to create a SHA-256 hash.
  • Hashes are useful for storing sensitive data like passwords in a secure way.

Password Hashing and Salt

For securing passwords, hashing alone is insufficient because attackers can use precomputed hash tables (rainbow tables) to reverse-engineer the original passwords. To make hashing more secure, we use salting, which involves adding a random value (salt) to the password before hashing it.

Example: Salting Passwords

				
					const bcrypt = require('bcrypt');
const saltRounds = 10;

// Hash password
async function hashPassword(password) {
    const salt = await bcrypt.genSalt(saltRounds);
    return await bcrypt.hash(password, salt);
}

// Verify password
async function verifyPassword(password, hash) {
    return await bcrypt.compare(password, hash);
}

// Usage
(async () => {
    const password = 'mysecurepassword';
    const hashedPassword = await hashPassword(password);
    console.log('Hashed Password:', hashedPassword);

    const isValid = await verifyPassword('mysecurepassword', hashedPassword);
    console.log('Password is valid:', isValid);
})();

				
			

Explanation:

  • bcrypt is used for salting and hashing passwords.
  • The compare function allows us to verify a user’s password against the stored hash.

Advanced Encryption Techniques: HMAC

HMAC (Hash-Based Message Authentication Code) is a technique that uses both a cryptographic hash function and a secret key to verify the integrity and authenticity of data.

Example: HMAC with SHA-256

				
					const crypto = require('crypto');

// HMAC function
function generateHMAC(key, message) {
    return crypto.createHmac('sha256', key).update(message).digest('hex');
}

// Usage
const key = 'mysecretkey';
const message = 'Important data';
const hmac = generateHMAC(key, message);
console.log('HMAC:', hmac);

				
			

Explanation:

  • HMAC is used to verify both the integrity and authenticity of the message.
  • In the example, a SHA-256 hash is generated using a secret key.

In this chapter, we have explored the world of data encryption and hashing within Node.js, starting with the basics of symmetric and asymmetric encryption, hashing techniques, password salting, and advanced cryptographic concepts like HMAC. By leveraging Node.js's crypto module and libraries like bcrypt, developers can secure their applications effectively. Encryption ensures data confidentiality, while hashing maintains data integrity, both of which are essential for building secure, modern applications.

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India