Skip to content

Instantly share code, notes, and snippets.

@noize-e
Last active February 14, 2024 10:21
Show Gist options
  • Save noize-e/5aa11be36f9d57be8ea8e0327907d9a0 to your computer and use it in GitHub Desktop.
Save noize-e/5aa11be36f9d57be8ea8e0327907d9a0 to your computer and use it in GitHub Desktop.
Secure Data Transmission with Node.js and Asymmetric Encryption

Secure Data Transmission with Node.js and Asymmetric Encryption

Description

This code is a JavaScript module that provides functions to encrypt sensitive data using both asymmetric (RSA) and symmetric (AES) encryption algorithms. The purpose of this module is to demonstrate a client-side encryption process that can be used to secure data before sending it to a server, ensuring that only the server with the corresponding private key can decrypt and access the data.

Prerequisites

To run this code, you need to have the node-forge library installed in your project. You can install it using npm:

npm install node-forge

Functions

encryptAESKey(AESKey, publicKey)

This function takes in a symmetric AES key (AESKey) and a server's public RSA key (publicKey) in PEM format. It encrypts the AES key using the RSA-OAEP (Optimal Asymmetric Encryption Padding) scheme and returns the encrypted result in Base64 format.

encryptText(text, key, iv)

This function takes in plaintext (text), a symmetric AES key (key), and an initialization vector (iv). It uses the AES-CBC (Cipher Block Chaining) encryption mode to encrypt the text using the provided key and iv. The function returns the encrypted result in hexadecimal format.

encryptPayload(payload)

This is the main function that encrypts the payload data before sending it to the server. It takes a JSON payload object containing sensitive data (e.g., username and password).

  1. A random symmetric key (symmetricKey) and initialization vector (iv) are generated, each consisting of 16 bytes.
  2. The server's public RSA key (serverPublicKey) is used to encrypt the symmetricKey using the encryptAESKey function.
  3. The payload data is serialized as a JSON string and encrypted using the symmetricKey and iv with the encryptText function.
  4. The result of step 3 (encrypted payload) is combined with the iv and encoded in Base64 format, creating a single string representing the encrypted payload and IV.
  5. The encrypted symmetric key (encryptedSymmetricKey) and the combined result from step 4 are returned as properties in an object.

Please note that the server's public RSA key (serverPublicKey) used in this code is provided as a static string for demonstration purposes. In a real-world scenario, the server's public key should be fetched securely from the server or some trusted source.

Usage

To use the encryptPayload function, simply import it into your code and call it with the appropriate payload object:

import encryptPayload from './path/to/EncryptPayload';

const payload = {
  username: 'example_username',
  password: 'example_password',
};

const encryptedData = encryptPayload(payload);
console.log('Encrypted Data:', encryptedData);

Please ensure that you have the node-forge library installed and accessible in your project when using this code. Additionally, use the encrypted data (encryptedData) to make the API call and send it to the server. The server will then use its private key to decrypt the symmetric key and subsequently decrypt the payload data securely.

import forge from 'node-forge';
const encryptAESKey = (AESKey, publicKey) => {
const publicKeyPem = forge.pki.publicKeyFromPem(publicKey);
const rsaEncryptedAesKey = publicKeyPem.encrypt(AESKey, 'RSA-OAEP');
return forge.util.encode64(rsaEncryptedAesKey);
}
const encryptText = (text, key, iv) => {
const cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({ iv: iv });
cipher.update(forge.util.createBuffer(text));
cipher.finish();
const encrypted = cipher.output;
return encrypted.toHex();
}
const encryptPayload = (payload) => {
// Generate a random symmetric key for AES encryption
const symmetricKey = forge.random.getBytesSync(16);
const iv = forge.random.getBytesSync(16);
// server's public RSA key (replace this with the actual key)
const serverPublicKey = `-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----`;
// Encrypt the symmetric key with the server's public RSA key
const encryptedSymmetricKey = encryptAESKey(symmetricKey, serverPublicKey)
// Encrypt the payload using the generated symmetric key
const encryptedPayload = encryptText(JSON.stringify(payload), symmetricKey, iv)
return { esk: encryptedSymmetricKey.toString(),
rep: forge.util.encode64(iv + encryptedPayload) }
};
export default encryptPayload;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment