Asymmetric encryption (Public-key cryptography) with Node.js


Asymmetric encryption (Public-key cryptography) with Node.js

How asymmetric encryption works?

There are two sides in an encrypted communication: the sender, who encrypts the data, and the recipient, who decrypts it. As the name implies, asymmetric encryption or public-key cryptography is different on each side; the sender and the recipient use two different keys.

A public key and Private keys are generated randomly using an algorithm, and the keys have a mathematical relationship with each other. The key should be longer in length (128 bits, 256 bits) to make it stronger and make it impossible to break the key even if the other paired key is known.

asymmetric encryption

In an asymmetric key encryption scheme, anyone can encrypt messages using a public key, but only the holder of the paired private key can decrypt such a message. The security of the system depends on the secrecy of the private key, which must not become known to any other.

Generating the public key and private key

I’ll present two methods to generate the keys, depending on your needs, but for the next section, I’ll present the first method, where the keys are stored in .pem files.

1. Using openssl

Generate private key

$ openssl genrsa -out private_key.pem 4096

Generate public key

openssl rsa -pubout -in private_key.pem -out public_key.pem

2. Using Crypto built-in library of Nodej.js

const crypto = require("crypto")

// The `generateKeyPairSync` method accepts two arguments:
// 1. The type ok keys we want, which in this case is "rsa"
// 2. An object with the properties of the key
const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
	// The standard secure default length for RSA keys is 2048 bits
	modulusLength: 2048,
})

How to use it in Node

I created two helper functions:

import fs from 'fs'
import crypto from 'crypto'

export function encryptText (plainText) {
  return crypto.publicEncrypt({
    key: fs.readFileSync('public_key.pem', 'utf8'),
    padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    oaepHash: 'sha256'
  },
  // We convert the data string to a buffer
  Buffer.from(plainText)
  )
}

export function decryptText (encryptedText) {
  return crypto.privateDecrypt(
    {
      key: fs.readFileSync('private_key.pem', 'utf8'),
      // In order to decrypt the data, we need to specify the
      // same hashing function and padding scheme that we used to
      // encrypt the data in the previous step
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
      oaepHash: 'sha256'
    },
    encryptedText
  )
}

Encrypt example

const plainText = "simple text";

const encryptedText = encryptText(plainText)
// encryptedText will be returned as Buffer
// in order to see it in more readble form, convert it to base64
console.log('encrypted text: ', encryptedText.toString('base64'))

The output:

encrypted text:  V8ZwxwmjCosiiUGclRbGpwkTqEcwOw/fy6Sfg+xQnCZY51rr5e93XbcyDEBjrmTfkLKQ/y/fwskajrfattp7Pb5nXH+yqRi0jJ/mL0BrpAvwpY+5TMmGRubaWMEk6AbkrmOV+rNg8SSro1wZNc7dyVttXP6pjuBSBM4Mc9GCFCNPq28aClwVFmByQfR4gS+WfYHXpavBWi+obc4C+JrfG9L3PT1Th0XHi49xWQxrlQRwKahe7vbtBJIxG8H/VlUqlZcnABw0caIago1VGJbMo1XdE/OTpgIqozcP76wjEZNdeuBhVS3hU50gW/qx7gm/SlWwIaHjvsm8sMMI60TnDs9OAkSRXt3LXtTk7H+PjtTl2+5e46PYC6MXvFtJgqZOz5csilT/AXp/on2n0DdZT+nLwe5/8IK2LylRbIm7+ICGbGE97tn9v+LuGplPO953pVRPLgtFxxcCEFiCPGPxoYWm+TDfF3XstjdjiHFAkVeVPPd+1Vtu1WxDKKtXIu1ALY552jZQApGTBhTDrL2GbKRVgrSZdO7oTPiSBZcknL1IoRAK6sn3X/58JFkMsfPhtjlMFJ1AWNC1l+8wxzMbDrwkMuUN2lodw5rvy+IquxQPJPFkCHjv8gpReNyDU7iLR8IPwX09FY3CaGuUR3x+de5kUDRIuP19CTGV8M6jL0g=

Decrypt example

  const decryptedText = decryptText(encryptedText)
  console.log('decrypted text:', decryptedText.toString())

The output:

decrypted text: simple text

If you need to decrypt from base64 string:

  const base64Encrypted = 'V8ZwxwmjCosiiUGclRbGpwkTqEcwOw/fy6Sfg+xQnCZY51rr5e93XbcyDEBjrmTfkLKQ/y/fwskajrfattp7Pb5nXH+yqRi0jJ/mL0BrpAvwpY+5TMmGRubaWMEk6AbkrmOV+rNg8SSro1wZNc7dyVttXP6pjuBSBM4Mc9GCFCNPq28aClwVFmByQfR4gS+WfYHXpavBWi+obc4C+JrfG9L3PT1Th0XHi49xWQxrlQRwKahe7vbtBJIxG8H/VlUqlZcnABw0caIago1VGJbMo1XdE/OTpgIqozcP76wjEZNdeuBhVS3hU50gW/qx7gm/SlWwIaHjvsm8sMMI60TnDs9OAkSRXt3LXtTk7H+PjtTl2+5e46PYC6MXvFtJgqZOz5csilT/AXp/on2n0DdZT+nLwe5/8IK2LylRbIm7+ICGbGE97tn9v+LuGplPO953pVRPLgtFxxcCEFiCPGPxoYWm+TDfF3XstjdjiHFAkVeVPPd+1Vtu1WxDKKtXIu1ALY552jZQApGTBhTDrL2GbKRVgrSZdO7oTPiSBZcknL1IoRAK6sn3X/58JFkMsfPhtjlMFJ1AWNC1l+8wxzMbDrwkMuUN2lodw5rvy+IquxQPJPFkCHjv8gpReNyDU7iLR8IPwX09FY3CaGuUR3x+de5kUDRIuP19CTGV8M6jL0g='

  const decryptedText = decryptText(Buffer.from(base64Encrypted, 'base64'))
  console.log('decrypted text', decryptedText.toString())
// decrypted text: simple text

Resources:

  1. Implementing RSA Encryption and Signing in Node.js (With Examples)</>
  2. Asymmetric encryption in Nodejs
  3. Public-key cryptography
  4. Crypto Node.js v16.0.0 documentation

Newsletter


Related Posts

Get your Jenkins Passwords from secrets

How to get your Jenkins passwords from your secrets credentials. Follow this simple tutoriale and find your password or ssh private key.

How to launch a 6 figures startup with 0$ investment

Are you curious how to launch a startup in the fast and effective way? Here's not the answer, but you can understand how to achieve it

How to cold email

How to cold email - a practical guide about how to use cold email in your activity as a CEO of a software agency or startup owner.

Linux disk space alerts on Discord

Linux disk space alerts. Check your space and be responsible with your project. Take care of your space and don't crack the project.

Git clone private repo in docker

A simple how to guide to use git clone of a private repository inside docker container. With vuejs / nodejs app.

How to detect the browser language in javascript

How to detect the browser language in javascript in just a line of code. The method is working on all major browser

You don't need a macbook pro to be a pro

You don't need a macbook pro to be a pro! You need a laptop and internet connection, and a brain, but you already have it

Free templates for startup

Free HTML templates for startup or a new project. A complete list with free resources to build your next startup's website and gain the traction to the sky.

What I learned to never do in a presentation meeting

What I learned to never do in a presentation meeting. I had a very bad meeting experience with a gateway provider.

Startup graveyard is a series of killed projects that made millions in revenue per year

Startup graveyard is a series of killed projects that made millions in revenue per year. Just watch their graveyard and do it your own. What better validation do you expect.