| const crypto = require("crypto"); |
| const { dumpENV } = require("../helpers/updateENV"); |
|
|
| |
| |
| class EncryptionManager { |
| #keyENV = "SIG_KEY"; |
| #saltENV = "SIG_SALT"; |
| #encryptionKey; |
| #encryptionSalt; |
|
|
| constructor({ key = null, salt = null } = {}) { |
| this.#loadOrCreateKeySalt(key, salt); |
| this.key = crypto.scryptSync(this.#encryptionKey, this.#encryptionSalt, 32); |
| this.algorithm = "aes-256-cbc"; |
| this.separator = ":"; |
|
|
| |
| |
| |
| this.xPayload = this.key.toString("base64"); |
| } |
|
|
| log(text, ...args) { |
| console.log(`\x1b[36m[EncryptionManager]\x1b[0m ${text}`, ...args); |
| } |
|
|
| #loadOrCreateKeySalt(_key = null, _salt = null) { |
| if (!!_key && !!_salt) { |
| this.log( |
| "Pre-assigned key & salt for encrypting arbitrary data was used." |
| ); |
| this.#encryptionKey = _key; |
| this.#encryptionSalt = _salt; |
| return; |
| } |
|
|
| if (!process.env[this.#keyENV] || !process.env[this.#saltENV]) { |
| this.log("Self-assigning key & salt for encrypting arbitrary data."); |
| process.env[this.#keyENV] = crypto.randomBytes(32).toString("hex"); |
| process.env[this.#saltENV] = crypto.randomBytes(32).toString("hex"); |
| if (process.env.NODE_ENV === "production") dumpENV(); |
| } else |
| this.log("Loaded existing key & salt for encrypting arbitrary data."); |
|
|
| this.#encryptionKey = process.env[this.#keyENV]; |
| this.#encryptionSalt = process.env[this.#saltENV]; |
| return; |
| } |
|
|
| encrypt(plainTextString = null) { |
| try { |
| if (!plainTextString) |
| throw new Error("Empty string is not valid for this method."); |
| const iv = crypto.randomBytes(16); |
| const cipher = crypto.createCipheriv(this.algorithm, this.key, iv); |
| const encrypted = cipher.update(plainTextString, "utf8", "hex"); |
| return [ |
| encrypted + cipher.final("hex"), |
| Buffer.from(iv).toString("hex"), |
| ].join(this.separator); |
| } catch (e) { |
| this.log(e); |
| return null; |
| } |
| } |
|
|
| decrypt(encryptedString) { |
| try { |
| const [encrypted, iv] = encryptedString.split(this.separator); |
| if (!iv) throw new Error("IV not found"); |
| const decipher = crypto.createDecipheriv( |
| this.algorithm, |
| this.key, |
| Buffer.from(iv, "hex") |
| ); |
| return decipher.update(encrypted, "hex", "utf8") + decipher.final("utf8"); |
| } catch (e) { |
| this.log(e); |
| return null; |
| } |
| } |
| } |
|
|
| module.exports = { EncryptionManager }; |
|
|