Nodejs Cryptography: Encrypt and Decrypt Data
Friday, January 12, 2024In the software development world, developers use cryptography and encryption techniques to secure sensitive data from malicious entities. They conduct a study on data security through cryptography. It is an approach that enables software developers to transform plaintext into encrypted text and vice versa. This means that transferring data in a secure and secret manner is possible with cryptography which eventually enables the receiver and sender to comprehend its contents.
Cryptographic algorithms use a key to change the plaintext into ciphertext, and when one has the correct key, it becomes easily possible to convert ciphertext back to plaintext.
Any organization uses symmetric encryption when it uses the same key to encode and decode the data. In contrast, asymmetric encryption is used when encrypting and decrypting the data involves a different set of keys. Additionally, it is necessary to keep hashed passwords in the database to secure the Node.js application data. This practice can disable anyone without the key to decode the encrypted data. And the concept of encoding and decoding the data helps secure them which is the main reason behind Nodejs cryptography being business by developers.
Here we will go through everything about Nodejs cryptography and how to encrypt and decode data in Node.js applications.
1. What is Nodejs Cryptography?
Cryptography is a process that enables the securing of communication and data by converting both of them into formats that can only be deciphered by the authorized party.
With Nodejs cryptography, the developers can hash passwords and save all the information into the database. After hashing the data, we cannot convert it to plain text. Additionally, if any malicious being gets hold of the database in any case, they won’t be able to decode the information as it will be encrypted. However, the type of encryption employed completely depends on the development team, its knowledge, and mainly on the application requirements. For example, Node.js applications can perform cryptography using various methods, including utilizing public keys for encryption and decryption, symmetric keys for hashing, and more. In addition to this, when implementing nodejs cryptography, the end party of the application receives encrypted data, which they can decrypt into plain text for their consumption. This means that the chance for cybercriminals to decrypt the encrypted data isn’t possible. This is what the Node.js crypto module enables software engineers to do.
2. Node.js Crypto Module
App developers use the Node.js crypto module in cryptography for Node.js, as it offers cryptographic functionality that secures the Node.js application from any type of threat or malfunction. The Node.js crypto module comes with a set of wrappers for HMAC, OpenSSL’s hash, sign, cipher, decipher, and verify functions. Node.js integrates crypto into the technology, eliminating the need for rigorous configurations and implementation processes. Besides this, Unlike other modules, you don’t need to install Crypto before you use it in your Node.js application.
Crypto enables developers to hash plain texts before storing them in the database .For this purpose, the development team needs to use a hash class that can create unidirectional, deterministic, fixed-length, and collision-resistant hashes. When hashing the data, a predetermined key cannot decrypt the password that opens it. In this case, you can utilize an HMAC class for a Hash-based Message Authentication Code, enabling the creation of a single final hash by hashing keys and values.
Besides this, when the developers want to encrypt and decrypt the hashed data of other users for transmission purposes, the team needs to utilize the Cipher and Decipher classes. In this case, the development team encrypts the data using the Cipher class and decrypts it with the Decipher class. In addition to this, when one wants to verify the hashed or encrypted password to validate it, Verify class is required and the Signing class is used for its certification. Because of all the reasons stated above, using the crypto module is necessary. So, now let’s explore the various crypto classes.
3. Node.js Crypto Classes
Node.js developers can utilize the top Node.js Crypto Classes to secure their clients’ application data.
3.1 Cipher
The Cipher class in Node.js Crypto is responsible for encrypting the data of the application. Whenever the user wants to input a password while registering, the system calls the Cipher class to encrypt the password. First, the developers need to create a key from a hashing algorithm, and later on they need to create a random initialization number before encrypting the text. This enables the Node.js development company to use the Cipher class in order to develop an instance of cipher by utilizing the crypto.createCipheriv() or crypto.createCipher().
In this case, the experts suggest using crypto.createCipheriv() more often as crypto.createCipher() is depreciated. Here in the below-given program, we will learn how the developers encrypt the passwords with the use of the Cipher method.
const crypto = require('crypto');
const cryptoAlgorithm = 'aes-192-cbc';// In this case aes192 algorithm is used, the key is 24 bytes (192 bits).
const cryptoPassword = 'TestCryptography';
// Generation of the key, as it is dependent on the algorithm.
crypto.scrypt(cryptoPassword, 'salt', 24, (err, key) => {
if (err) {
console.log('Error:', err);
}
// Generation of a random iv (initialization vector)
crypto.randomFill(new Uint8Array(16), (err, iv) => {
if (err) {
console.log('Random fill error:', err);
}
// Create Cipher with key and iv
const cipher = crypto.createCipheriv(cryptoAlgorithm, key, iv);
let encrypted = '';
cipher.setEncoding('hex');
cipher.on('data', (chunk) => encrypted += chunk);
cipher.on('end', () => console.log('Encrypted Text:', encrypted));// Prints encrypted data with key
cipher.write('some clear text data');
cipher.end();
});
});
3.2 Decipher
When it comes to the Node js crypto module, the decipher class enables the software engineers to decrypt the encrypted texts. This means that when the developers want to send the information securely to another team, encryption is required. The only way to get the data and read it is to decrypt it. This is the process that the Decipher class carries out. Besides this, when it comes to using the decipher class and creating decipher objects with the new keyword, methods like crypto.createDecipheriv() or crypto.createDecipher() can be utilized in order to create decipher instances. But as per the expert’s advice, crypto.createdeCipheriv() method must be used instead of crypto.createDecipher().
In the below program, we will see how to use Decipher class to decipher the encrypted text.
const crypto = require('crypto');
const algorithm = 'aes-192-cbc'; // In this case aes192 algorithm is used, the key is 24 bytes (192 bits).
const password = 'TestCryptography';
// Generation of the key, as it is dependent on the algorithm.
// For deciphering.
const key = crypto.scryptSync(password, 'salt', 24);
// The IV is passed along with the cipher-text.
const iv = Buffer.alloc(16, 0); // Initialization vector.
// Creation of decipher with key and iv
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = '';
decipher.on('readable', (chunk) => {
while (null !== (chunk = decipher.read())) {
decrypted += chunk.toString('utf8');
}
});
decipher.on('end', () => {
console.log('Decrypted Text:', decrypted); // Print text data
});
// Encrypted with the same algorithm, key, and iv.
const encrypted =
'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
decipher.write(encrypted, 'hex');
decipher.end();
3.3 Hash
In Node.js, when the developer wants to hash the plain text, they use the Hash class. The reason behind it is that hashing is a very simple process that helps them to convert plain text into hash functions. Hashing text renders it unable to be converted back to its original form, implying that creating hash objects solely by employing new keywords is not possible.Besides, when the developers want to create a hash instance, using the crypto.createHash() method is the best option.
Here we will go through a program that shows how any developer can use crypto.createHash() to create a hash instance.
const crypto = require('crypto');
// Create a hash algorithm
const hash = crypto.createHash('sha256');
hash.on('readable', () => {
// Only one element gets produce by hash data
const hashData = hash.read();
if (hashData) {
console.log('Hashed Data:', hashData.toString('hex'));
// Prints the output:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
}
});
hash.write('some data to hash');
hash.end();
3.4 Certificate
The developer uses a certificate, which is a combination of a key pair and other information, when working with the Node.js crypto module to encrypt electronic documents. Basically, a certificate is an approach that can create a session key in order to transmit the information of the client securely over the internet. This shows that with the help of the crypto Certificate class, the developers can help the businesses work with Signed Public Key and Challenge (SPKAC). And for this OpenSSL can be used for SPKAC implementation.
Here is an example of how the developers use the Certificate class.
const { Certificate } = require('crypto');
const certificate = getSpkacSomehow();
const challenge = Certificate.exportChallenge(certificate);
console.log('Challenge:', challenge.toString('utf8'));
// Prints: the challenge as a UTF8 string
3.5 DiffieHellman
To decipher the cryptograph successfully, one requires a key. In this case, a key is similar to a shared secret between the receiving and the sending party. Here, if the keys aren’t secure, the hackers can easily get ahold of the key and eventually the entire user data which can create havoc. To avoid this situation, the developers use crypto’s DiffieHellman class as it comes with Diffie-Hellman key exchange which is an interesting method to secure the data by passing cryptographic keys in public channels. In addition to this, DiffieHellman offers secure keys that are for the sender and receiver of the data.
Here is the code that shows how the developers can use the DiffieHellman method.
const crypto = require('crypto');
const assert = require('assert');
// Generate Eve's keys
const eve = crypto.createDiffieHellman(2048);
const eveKey = eve.generateKeys();
// Generate Dave's keys
const dave = crypto.createDiffieHellman(eve.getPrime(), eve.getGenerator());
const daveKey = dave.generateKeys();
// Exchange and generate the secret
const eveSecret = eve.computeSecret(daveKey);
const daveSecret = dave.computeSecret(eveKey);
assert.strictEqual(eveSecret.toString('hex'), daveSecret.toString('hex'));
3.6 ECDH
ECDH stands for Elliptic-curve Diffie–Hellman. Node.js developers use this approach to establish a shared public-private key pair to support the elliptic curve.
Below is an example that shows how the developers can utilize the ECDH class in their projects.
const crypto = require('crypto');
const assert = require('assert');
// Generate Eve's keys
const eve = crypto.createECDH('secp521r1');
const eveKey = eve.generateKeys();
// Generate Dave's keys
const dave = crypto.createECDH('secp521r1');
const daveKey = dave.generateKeys();
// Exchange and generate the secret
const eveSecret = eve.computeSecret(daveKey);
const daveSecret = dave.computeSecret(eveKey);
assert.strictEqual(eveSecret.toString('hex'), daveSecret.toString('hex'));
3.7 HMAC
HMAC stands for Hash-based message authentication code that allows Node.js development companies to offer digital signatures by using a shared secret approach. Besides, when the developer wants to use the HMAC method, they have to make use of crypto’s HMAC class for digital signing.
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'secret key');
hmac.on('readable', () => {
// Only one element gets produce by hash stream
const streamData = hmac.read();
if (streamData) {
console.log('Stream Data:', streamData.toString('hex'));
// Prints output:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
}
});
hmac.write('some data to hash');
hmac.end();
3.8 Sign
In Node.js crypto, developers use the sign class to create signatures. They need to employ the Sign class when they want to provide efficient cryptography to businesses and later sign and verify cryptographs for authentication. By following this method, when the receiver of the data gets a cryptograph they can easily identify the genuineness of the signature and verify it.
Developers use the Sign class in the code to demonstrate its functionality.
const crypto = require('crypto');
const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
namedCurve: 'sign15K1'
});
// Create sign
const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');
3.9 Verify
When businesses are working with hashed cryptography and they want to ascertain its value, the only way to do so is to use the verify method. For example, when a user is registering, developers need to create a system that hashes and stores the user’s password in the database of any business organization. Subsequently, when the user logs in, the system must confirm the password. Since the hashed password cannot be deciphered, the only way to carry out the entire process is by using the verify class.
Here is the code that shows the usage of the verify class to make sure that the hashed cryptography is correct.
// Verify the signed token from the `sign` example above
const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log('Verify Data:', verify.verify(publicKey, signature, 'hex'));
// Prints: true
4. How to Encrypt Data in Node.js?
Any Node.js developer who wants to encrypt data for a client’s business application needs to follow a specific process, as follows:
To start data encryption in Node.js, create the encrypt.js file first and then define the encryption functions. Here, in the initial stage, the developer needs to import the crypto module.
const crypto = require ("crypto");
And when the developer is encrypting data, it becomes essential to use a cryptographic algorithm. Here we have used aes-256-cbc and have also used crypto.randomBytes() method as it helps in cryptographically generating random data. Additionally, the initialization vector (initVector) holds the random data of 16 bytes in size from the randomBytes() method, along with the Securitykey containing random data of 32 bytes in size.
Here is the code that shows the entire process.
// crypto module
const crypto = require("crypto");
const algorithm = "aes-256-cbc";
// generate 16 bytes of random data
const initVector = crypto.randomBytes(16);
// protected data
const message = "Secret Message";
// secret key generates 32 bytes of random data
const Securitykey = crypto.randomBytes(32);
When you want to encrypt the data, use the cipher function. In this program, we have used createCipheriv() as a cipher function in order to initialize the vector from the crypto module. To do so, pass the algorithm as the first argument, use the Security key as the second argument of the program, and set the initVector as the third one. Besides, in order to encrypt the message, the usage of the update() method on the cipher is necessary.
// crypto module
const crypto = require("crypto");
const algorithm = "aes-256-cbc";
// generate 16 bytes of random data
const initVector = crypto.randomBytes(16);
// protected data
const message = "Secret Message";
// secret key generates 32 bytes of random data
const Securitykey = crypto.randomBytes(32);
//The cipher function
const cipher = crypto.createCipheriv(algorithm, Securitykey, initVector);
//Encrypt the message
// input encoding
// output encoding
let encryptedData = cipher.update(message, "utf-8", "hex");
The final() method helps the cipher to stop the encryption process by the code here. Calling this method renders the cipher unusable for encrypting the user’s data more than once. After invoking the final() method, it encrypts the message, rendering it resistant to decoding by malicious attackers due to its usage.
Here is the code that shows how to encrypt data.
// crypto module
const crypto = require("crypto");
const algorithm = "aes-256-cbc";
// generate 16 bytes of random data
const initVector = crypto.randomBytes(16);
// protected data
const message = "Secret Message";
// secret key generates 32 bytes of random data
const securityKey = crypto.randomBytes(32);
//The cipher function
const cipher = crypto.createCipheriv(algorithm, securityKey, initVector);
//Encrypt the message
let encryptedData = cipher.update(message, "utf-8", "hex");
encryptedData += cipher.final("hex");
console.log("The encrypted message is:", encryptedData);
Here is the output:
5. How to Decrypt Data in Node.js?
To decrypt the data in Node.js, software development companies follow a specific method that is quite similar to that of data encryption. Here in the below-given program, we have used the decipher function to decrypt data. So, let us have a look at the code in the decrypt.js file and see how to decrypt the data.
// crypto module
const crypto = require("crypto");
const algorithm = "aes-256-cbc";
// generate 16 bytes of random data
const initVector = crypto.randomBytes(16);
// protected data
const message = "Secret Message";
// secret key generates 32 bytes of random data
const securityKey = crypto.randomBytes(32);
//The cipher function
const cipher = crypto.createCipheriv(algorithm, securityKey, initVector);
//Encrypt the message
let encryptedData = cipher.update(message, "utf-8", "hex");
encryptedData += cipher.final("hex");
console.log("The encrypted message is:", encryptedData);
//Decrypt the message
const decipher = crypto.createDecipheriv(algorithm, securityKey, initVector);
let decryptedData = decipher.update(encryptedData, "hex", "utf-8");
decryptedData += decipher.final("utf8");
console.log("The decrypted message is:", decryptedData);
Here is the output:
6. Conclusion
This blog highlights that software development companies use Node.js Crypto as one of the widely employed approaches for encrypting and decrypting data, ensuring the confidentiality of messages exchanged between the receiver and sender. Developers leverage this concept to encrypt passwords and essential user data, enabling them to create a chat application that not only encrypts the message before forwarding it to the other user but also facilitates other security measures. This helps in safeguarding the message from hackers. To implement all these things for your client’s application, you can follow the above-listed encryption and decryption process by using the Node.js Crypto module.
7. FAQ
How to encrypt and decrypt Node js?
The inbuilt library known as crypto comes with NodeJS, and it can be used to encrypt and decrypt the data. It contains various crypto algorithms for the same, making it suitable for any type of data. Here is an example of encrypting and decrypting data:
//Checking the crypto module
const crypto = require('crypto');
const algorithm = 'aes-256-cbc'; //Using AES encryption
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
//Encrypting text
function encrypt(text) {
let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
}
// Decrypting text
function decrypt(text) {
let iv = Buffer.from(text.iv, 'hex');
let encryptedText = Buffer.from(text.encryptedData, 'hex');
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
}
// Text send to encrypt function
var hw = encrypt("Welcome to Tutorials Point...")
console.log(hw)
console.log(decrypt(hw))
When someone runs this code, they can see the following output.
C:\Users\mysql-test>> node encrypt.js
{ iv: '61add9b0068d5d85e940ff3bba0a00e6', encryptedData:
'787ff81611b84c9ab2a55aa45e3c1d3e824e3ff583b0cb75c20b8947a4130d16' }
//Encrypted text
Welcome to Tutorials Point... //Decrypted text
Which modules can be used to perform encryption and decryption in Node JS?
In NodeJS, the crypto module offers cryptographic functions to encrypt and decrypt the code. It uses wrappers like HMAC, hash, cipher, and decipher.
Comments