diff --git a/src/renderer/src/dependencies/simple.js b/src/renderer/src/dependencies/simple.js index e51ca67fb..7f87fd0c5 100644 --- a/src/renderer/src/dependencies/simple.js +++ b/src/renderer/src/dependencies/simple.js @@ -1,4 +1,4 @@ -import { app, isElectron } from "../electron/index.js"; +import { app, crypto, isElectron } from "../electron/index.js"; import paths from "../../../../paths.config.json" assert { type: "json" }; import { joinPath } from "../globals.js"; @@ -19,4 +19,14 @@ export const conversionSaveFolderPath = homeDirectory ? joinPath(homeDirectory, paths["root"], ...paths.subfolders.conversions) : ""; +// Encryption +const IV_LENGTH = 16; +const KEY_LENGTH = 32; +export const ENCRYPTION_KEY = homeDirectory + ? Buffer.concat([Buffer.from(homeDirectory), Buffer.alloc(KEY_LENGTH)], KEY_LENGTH) + : null; + +export const ENCRYPTION_IV = crypto ? crypto.randomBytes(IV_LENGTH) : null; + +// Storybook export const isStorybook = window.location.href.includes("iframe.html"); diff --git a/src/renderer/src/electron/index.js b/src/renderer/src/electron/index.js index afa72cb06..b36779b00 100644 --- a/src/renderer/src/electron/index.js +++ b/src/renderer/src/electron/index.js @@ -14,6 +14,11 @@ export let path = null; export let log = null; export let crypto = null; +// Used in tests +try { + crypto = require("crypto"); +} catch {} + if (isElectron) { try { fs = require("fs-extra"); // File System diff --git a/src/renderer/src/progress/index.js b/src/renderer/src/progress/index.js index 14bc2a2f1..7c581d4b9 100644 --- a/src/renderer/src/progress/index.js +++ b/src/renderer/src/progress/index.js @@ -5,7 +5,8 @@ import { reloadPageToHome, isStorybook, appDirectory, - homeDirectory, + ENCRYPTION_KEY, + ENCRYPTION_IV, } from "../dependencies/simple.js"; import { fs, crypto } from "../electron/index.js"; @@ -18,32 +19,44 @@ import * as operations from "./operations"; export * from "./update"; -var re = /[0-9A-Fa-f]{6}/g; +const CRYPTO_VERSION = "0.0.1"; // NOTE: Update to wipe values created using an outdated encryption algorithm +const CRYPTO_ALGORITHM = "aes-256-cbc"; -function encode(message) { - if (!crypto) return message; - const mykey = crypto.createCipher("aes-128-cbc", homeDirectory); - const mystr = mykey.update(message, "utf8", "hex"); - return mystr + mykey.final("hex"); +function encode(text) { + if (!crypto) return text; + const cipher = crypto.createCipheriv(CRYPTO_ALGORITHM, ENCRYPTION_KEY, ENCRYPTION_IV); + + const encrypted = cipher.update(text); + return CRYPTO_VERSION + Buffer.concat([encrypted, cipher.final()]).toString("hex"); } // Try to decode the value -function decode(message) { - if (!crypto || !/[0-9A-Fa-f]{6}/g.test(message)) return message; +function decode(text) { + if (!crypto || !/[0-9A-Fa-f]{6}/g.test(text)) return text; + if (text.slice(0, CRYPTO_VERSION.length) !== CRYPTO_VERSION) return undefined; + + text = text.slice(CRYPTO_VERSION.length); try { - const mykey = crypto.createDecipher("aes-128-cbc", homeDirectory); - const mystr = mykey.update(message, "hex", "utf8"); - return mystr + mykey.final("utf8"); + let textParts = text.split(":"); + let encryptedText = Buffer.from(textParts.join(":"), "hex"); + let decipher = crypto.createDecipheriv(CRYPTO_ALGORITHM, ENCRYPTION_KEY, ENCRYPTION_IV); + let decrypted = decipher.update(encryptedText); + decrypted = Buffer.concat([decrypted, decipher.final()]); + return decrypted.toString(); } catch { - return message; + return text; } } function drill(o, callback) { if (o && typeof o === "object") { const copy = Array.isArray(o) ? [...o] : { ...o }; - for (let k in copy) copy[k] = drill(copy[k], callback); + for (let k in copy) { + const res = drill(copy[k], callback); + if (res) copy[k] = res; + else delete copy[k]; + } return copy; } else return callback(o); }