Skip to content

Instantly share code, notes, and snippets.

@jeremybradbury
Last active October 16, 2021 01:30
Show Gist options
  • Save jeremybradbury/ec34a117ec6876783087807d5dcc693b to your computer and use it in GitHub Desktop.
Save jeremybradbury/ec34a117ec6876783087807d5dcc693b to your computer and use it in GitHub Desktop.
RSA Encrypt & Decrypt NodeJS Module (v12+, no deps)
const {
generateKeyPairSync,
privateDecrypt,
publicEncrypt,
constants: { RSA_PKCS1_OAEP_PADDING },
} = require("crypto"); // core node
const {
CRYPTIC_PASSPHRASE, // set to enable for your private key (changes require new keys)
CRYPTIC_GENERATE_KEYS, // set CRYPTIC_GENERATE_KEYS=1 to write key files
} = process.env;
const { error, debug } = require('console'); // core node (i actually winston at `info` on prod, `debug` level locally)
const { writeFile, readFile } = require('fs').promises; // core node
let privateKey = '';
let publicKey = '';
let options = {
padding: RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
};
const generateKeys = async () => {
const privateKeyEncoding = {
type: 'pkcs8',
format: 'pem',
};
if (CRYPTIC_PASSPHRASE) {
privateKeyEncoding.cipher = 'aes-256-cbc';
privateKeyEncoding.passphrase = CRYPTIC_PASSPHRASE;
}
const { publicKey, privateKey } = generateKeyPairSync("rsa", {
modulusLength: 8192,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
privateKeyEncoding,
});
try {
await writeFile('./public.pem', publicKey.toString());
await writeFile('./private.pem', privateKey.toString());
return { publicKey, privateKey };
} catch(err) {
error(err);
}
};
if (CRYPTIC_GENERATE_KEYS) {
generateKeys();
}
const setPublicKey = async () => {
try {
privateKey = await readFile('./private.pem', 'utf8')
} catch (err) {
error(err);
}
}
const setPrivateKey = async () => {
try {
publicKey = await readFile('./public.pem', 'utf8');
} catch (err) {
error(err);
}
}
setPublicKey();
setPrivateKey();
const encrypt = (text) => {
debug(text); // hide these in prod
const opts = {...options, key: publicKey};
let data = publicEncrypt(
opts,
Buffer.from(text, 'utf8') // convert the data string
);
data = data.toString('base64');
data = encodeURIComponent(data); // url encoded
debug(data); // hide these in prod
return data;
}
const decrypt = (cypher) => {
cypher = decodeURIComponent(cypher); // url decoded
debug(cypher); // hide these in prod
const opts = {...options, key: privateKey};
if (CRYPTIC_PASSPHRASE) {
opts.passphrase = CRYPTIC_PASSPHRASE;
}
const data = privateDecrypt(
opts,
Buffer.from(cypher, 'base64')
)
debug(data.toString()); // hide these in prod
return data.toString();
}
module.exports = {
decrypt,
encrypt,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment