diff --git a/API.md b/API.md index c5639a9..cde07ce 100644 --- a/API.md +++ b/API.md @@ -40,6 +40,23 @@ The central paste entity has the following fields: * `metadata` (key-value store) * Different frontends may store simple key-value metadata pairs on pastes to enable specific functionality (for example clientside encryption) +### Encryption + +The frontend pasty ships with implements an encryption option. This en- and decrypts pastes clientside and appends the HEX-encoded en-/decryption key to the paste URL (after a `#` because the so called **hash** is not sent to the server). +If a paste is encrypted using this feature, its `metadata` field contains a field like this: + +```jsonc +{ + // --- omitted other entity field + "metadata": { + "pf_encryption": { + "alg": "AES-CBC", // The algorithm used to encrypt the paste (currently, only AES-CBC is used) + "iv": "54baa80cd8d8328dc4630f9316130f49" // The HEX-encoded initialization vector of the AES-CBC encryption + } + } +} +``` + ## Endpoints ### [UNSECURED] Retrieve application information diff --git a/web/assets/css/style.css b/web/assets/css/style.css index 4ca65d9..68de6c6 100644 --- a/web/assets/css/style.css +++ b/web/assets/css/style.css @@ -130,6 +130,10 @@ html, body { transition: all 250ms; } +.navigation .button.active svg { + stroke: #2daa57; +} + .navigation .button:hover { cursor: pointer; } diff --git a/web/assets/css/style.css.map b/web/assets/css/style.css.map index 13102d1..aac5f9a 100644 --- a/web/assets/css/style.css.map +++ b/web/assets/css/style.css.map @@ -1,6 +1,6 @@ { "version": 3, - "mappings": "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", + "mappings": "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", "sources": [ "style.scss" ], diff --git a/web/assets/css/style.scss b/web/assets/css/style.scss index d1028e2..6435d4b 100644 --- a/web/assets/css/style.scss +++ b/web/assets/css/style.scss @@ -109,6 +109,9 @@ html, body { & svg { transition: all 250ms; } + &.active svg { + stroke: #2daa57; + } &:hover { cursor: pointer; & svg { diff --git a/web/assets/js/modules/encryption.js b/web/assets/js/modules/encryption.js new file mode 100644 index 0000000..75fba15 --- /dev/null +++ b/web/assets/js/modules/encryption.js @@ -0,0 +1,60 @@ +// Encrypts a piece of text using AES-CBC and returns the HEX-encoded key, initialization vector and encrypted text +export async function encrypt(encryptionData, text) { + const key = encryptionData.key; + const iv = encryptionData.iv; + + const textBytes = aesjs.padding.pkcs7.pad(aesjs.utils.utf8.toBytes(text)); + + const aes = new aesjs.ModeOfOperation.cbc(key, iv); + const encrypted = aes.encrypt(textBytes); + + return { + key: aesjs.utils.hex.fromBytes(key), + iv: aesjs.utils.hex.fromBytes(iv), + result: aesjs.utils.hex.fromBytes(encrypted) + }; +} + +// Decrypts an encrypted piece of AES-CBC encrypted text +export async function decrypt(keyHex, ivHex, inputHex) { + const key = aesjs.utils.hex.toBytes(keyHex); + const iv = aesjs.utils.hex.toBytes(ivHex); + const input = aesjs.utils.hex.toBytes(inputHex); + + const aes = new aesjs.ModeOfOperation.cbc(key, iv); + const decrypted = aesjs.padding.pkcs7.strip(aes.decrypt(input)); + + return aesjs.utils.utf8.fromBytes(decrypted); +} + +// Creates encryption data from hex key and IV +export async function encryptionDataFromHex(keyHex, ivHex) { + return { + key: aesjs.utils.hex.toBytes(keyHex), + iv: aesjs.utils.hex.toBytes(ivHex) + }; +} + +// Generates encryption data to pass into the encrypt function +export async function generateEncryptionData() { + return { + key: await generateKey(), + iv: generateIV() + }; +} + +// Generates a new 256-bit AES-CBC key +async function generateKey() { + const key = await crypto.subtle.generateKey({ + name: "AES-CBC", + length: 256 + }, true, ["encrypt", "decrypt"]); + + const extracted = await crypto.subtle.exportKey("raw", key); + return new Uint8Array(extracted); +} + +// Generates a new cryptographically secure 16-byte array which is used as the initialization vector (IV) for AES-CBC +function generateIV() { + return crypto.getRandomValues(new Uint8Array(16)); +} \ No newline at end of file diff --git a/web/assets/js/modules/state.js b/web/assets/js/modules/state.js index dcc0428..f063d7c 100644 --- a/web/assets/js/modules/state.js +++ b/web/assets/js/modules/state.js @@ -2,6 +2,7 @@ import * as API from "./api.js"; import * as Notifications from "./notifications.js"; import * as Spinner from "./spinner.js"; import * as Animation from "./animation.js"; +import * as Encryption from "./encryption.js"; const CODE_ELEMENT = document.getElementById("code"); const LINE_NUMBERS_ELEMENT = document.getElementById("linenos"); @@ -20,10 +21,15 @@ const BUTTONS_EDIT_ELEMENT = document.getElementById("buttons_edit"); const BUTTON_EDIT_CANCEL_ELEMENT = document.getElementById("btn_edit_cancel"); const BUTTON_EDIT_APPLY_ELEMENT = document.getElementById("btn_edit_apply"); +const BUTTON_TOGGLE_ENCRYPTION_ELEMENT = document.getElementById("btn_toggle_encryption"); + let PASTE_ID; let LANGUAGE; let CODE; +let ENCRYPTION_KEY; +let ENCRYPTION_IV; + let EDIT_MODE = false; let API_INFORMATION = { @@ -39,6 +45,11 @@ export async function initialize() { setupButtonFunctionality(); setupKeybinds(); + // Enable encryption if enabled from last session + if (localStorage.getItem("encryption") === "true") { + BUTTON_TOGGLE_ENCRYPTION_ELEMENT.classList.add("active"); + } + if (location.pathname !== "/") { // Extract the paste data (ID and language) const split = location.pathname.replace("/", "").split("."); @@ -56,7 +67,26 @@ export async function initialize() { // Set the persistent paste data PASTE_ID = pasteID; LANGUAGE = language; - CODE = (await response.json()).content; + + // Decode the response and decrypt the content if needed + const json = await response.json(); + CODE = json.content; + if (json.metadata.pf_encryption) { + ENCRYPTION_KEY = location.hash.replace("#", ""); + while (ENCRYPTION_KEY.length == 0) { + ENCRYPTION_KEY = prompt("Your decryption key:"); + } + + try { + CODE = await Encryption.decrypt(ENCRYPTION_KEY, json.metadata.pf_encryption.iv, CODE); + ENCRYPTION_IV = json.metadata.pf_encryption.iv; + } catch (error) { + console.log(error); + Notifications.error("Could not decrrypt paste; make sure the decryption key is correct."); + setTimeout(() => location.replace(location.protocol + "//" + location.host), 3000); + return; + } + } // Fill the code block with the just received data updateCode(); @@ -231,8 +261,24 @@ function setupButtonFunctionality() { return; } + // Encrypt the paste if needed + let value = INPUT_ELEMENT.value; + let metadata; + let key; + if (BUTTON_TOGGLE_ENCRYPTION_ELEMENT.classList.contains("active")) { + const encrypted = await Encryption.encrypt(await Encryption.generateEncryptionData(), value); + value = encrypted.result; + metadata = { + pf_encryption: { + alg: "AES-CBC", + iv: encrypted.iv + } + }; + key = encrypted.key; + } + // Try to create the paste - const response = await API.createPaste(INPUT_ELEMENT.value); + const response = await API.createPaste(value, metadata); if (!response.ok) { Notifications.error("Error while creating paste: " + await response.text() + ""); return; @@ -245,7 +291,7 @@ function setupButtonFunctionality() { } // Redirect the user to his newly created paste - location.replace(location.protocol + "//" + location.host + "/" + data.id); + location.replace(location.protocol + "//" + location.host + "/" + data.id + (key ? "#" + key : "")); }); }); @@ -297,8 +343,15 @@ function setupButtonFunctionality() { return; } + // Re-encrypt the paste data if needed + let value = INPUT_ELEMENT.value; + if (ENCRYPTION_KEY && ENCRYPTION_IV) { + const encrypted = await Encryption.encrypt(await Encryption.encryptionDataFromHex(ENCRYPTION_KEY, ENCRYPTION_IV), value); + value = encrypted.result; + } + // Try to edit the paste - const response = await API.editPaste(PASTE_ID, modificationToken, INPUT_ELEMENT.value); + const response = await API.editPaste(PASTE_ID, modificationToken, value); if (!response.ok) { Notifications.error("Error while editing paste: " + await response.text() + ""); return; @@ -311,6 +364,11 @@ function setupButtonFunctionality() { Notifications.success("Successfully edited paste."); }); + BUTTON_TOGGLE_ENCRYPTION_ELEMENT.addEventListener("click", () => { + const active = BUTTON_TOGGLE_ENCRYPTION_ELEMENT.classList.toggle("active"); + localStorage.setItem("encryption", active); + }); + BUTTON_REPORT_ELEMENT.addEventListener("click", async () => { // Ask the user for a reason const reason = prompt("Reason:"); diff --git a/web/index.html b/web/index.html index f246eb7..9ecb967 100644 --- a/web/index.html +++ b/web/index.html @@ -95,6 +95,18 @@ +
+ +
@@ -118,6 +130,7 @@
+