This content originally appeared on Bits and Pieces - Medium and was authored by Tony
How you can use Node’s built-in crypto module to correctly perform the (symmetric) encryption/decryption operations to secure data for your applications.
Encryption operations can be tricky, so much that paid encryption-as-a-service companies exist just to ensure that cryptographic operations are implemented correctly in codebases. The good news is that, with some little learning, you can make do with proper encryption for free with Node’s built-in crypto module.
In this guide, we explore how you can use Node’s built-in crypto module to correctly perform the (symmetric) encryption/decryption operations to secure data for your applications.
To begin, we need to understand the concept of symmetric encryption.
Symmetric Encryption
When people talk about “encryption,” they tend to mean symmetric encryption which is useful for encrypting text into a random string of characters. A common scenario where this is relevant is encrypting user data on a server so that it’s stored “encrypted at rest” in a database.
In layman terms, symmetric encryption is when you take the text you want to encrypt (called the plaintext) and use a secret key with an encryption algorithm to output the encrypted text (called the ciphertext). The operation is reversible and so decryption is when we can use the same secret with the plaintext
Now that we’ve outlined symmetric encryption, the best way to explain how to correctly perform the encryption is to demonstrate a proper implementation of using Node’s built-in crypto module for encryption with the aes-256-gcm algorithm.
Encryption
const encryptSymmetric = (key, plaintext) => {
// create a random initialization vector
const iv = crypto.randomBytes(12).toString('base64');
// create a cipher object
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
// update the cipher object with the plaintext to encrypt
let ciphertext = cipher.update(plaintext, 'utf8', 'base64');
// finalize the encryption process
ciphertext += cipher.final('base64');
// retrieve the authentication tag for the encryption
const tag = cipher.getAuthTag();
return { ciphertext, iv, tag };
}
Decryption
const decryptSymmetric = (key, ciphertext, iv, tag) => {
// create a decipher object
const decipher = crypto.createDecipheriv(
"aes-256-gcm",
Buffer.from(key, 'base64'),
Buffer.from(iv, 'base64')
);
// set the authentication tag for the decipher object
decipher.setAuthTag(Buffer.from(tag, 'base64'));
// update the decipher object with the base64-encoded ciphertext
let plaintext = decipher.update(ciphertext, 'base64', 'utf8');
// finalize the decryption process
plaintext += decipher.final('utf8');
return plaintext;
}
Usage
// some plaintext you want to encrypt
const plaintext = "The quick brown fox jumps over the lazy dog";
// create or bring your own encryption key
const key = crypto.randomBytes(32).toString('base64');
// encryption
const { ciphertext, iv, tag } = encryptSymmetric(key, iv, plaintext);
// decryption
const plaintext = decryptSymmetric(key, ciphertext, iv, tag);
In the above implementation, we work with base64 format to keep the data we work with as strings, although you can feel free stick to any other formats like hex . We define encryptSymmetric and decryptSymmetric functions to help us encrypt and decrypt data with a provided key :
- encryptSymmetric : This method helps us encrypt the plaintext using a 256-bit symmetric key . It outputs the encryption ciphertext and an iv that should be stored together for decryption later.
- decryptSymmetric : This method helps us decrypt the ciphertext using a 256-bit symmetric key.
- key : A generated/provided base64-encoded, 256-bit symmetric key used to encrypt/decrypt data. The key can be generated either through the code above or with openssl with the command openssl rand -base64 32 .
Awesome! Using these methods and an encryption key, you can now securely encrypt/decrypt data.
Lastly, your data is only as secure as the keys used to encrypt the data. As such, I strongly recommend securely storing encryption keys and accessing them in your application as environment variables or fetching them back from a secret manager like Infisical at runtime. This is simple to set up and worthwhile to learn.
Resources
Encryption/decryption can be a tricky subject, especially for folks with limited prior cryptography experience. So, before we part ways, I wanted to leave you with some resources:
- The Node Crypto Documentation
- Crypto 101: A great introductory book about cryptography for folks who want to dive deeper.
Build Apps with reusable components, just like Lego
Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Learn more:
- Creating a Developer Website with Bit components
- How We Build Micro Frontends
- How we Build a Component Design System
- How to reuse React components across your projects
- 5 Ways to Build a React Monorepo
- How to Create a Composable React App with Bit
- How to Reuse and Share React Components in 2023: A Step-by-Step Guide
- 5 Tools for Building React Component Libraries in 2023
Quickstart to Node’s Crypto Module for Encryption/Decryption was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Tony
Tony | Sciencx (2023-05-12T02:54:35+00:00) Quickstart to Node’s Crypto Module for Encryption/Decryption. Retrieved from https://www.scien.cx/2023/05/12/quickstart-to-nodes-crypto-module-for-encryption-decryption/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.