Last active
October 16, 2021 01:30
-
-
Save jeremybradbury/ec34a117ec6876783087807d5dcc693b to your computer and use it in GitHub Desktop.
RSA Encrypt & Decrypt NodeJS Module (v12+, no deps)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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