added manual salt, IV and key options

This commit is contained in:
dogeystamp 2023-01-03 20:44:47 -05:00
parent 45910aedfb
commit f49f072fab
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38
2 changed files with 86 additions and 35 deletions

View File

@ -1,22 +1,41 @@
let encForm = new Form({label: "Encryption"});
let encMsg = encForm.createTextArea({label: "Message"});
let encPass = encForm.createPasswordInput({label: "Password"});
let encManualMode = encForm.createCheckBox({
label: "Manual mode",
advanced: true
let encPass = encForm.createPasswordInput({
label: "Password",
enabledFunc: function() {return !encManualKey.value}
});
let encSalt = encForm.createTextBox({
let encSalt = encForm.createMediumTextBox({
label: "PBKDF2 salt",
dataType: "b64",
advanced: true,
disabled: true
enabled: false,
enabledFunc: function() {return encManualSalt.value && !encManualKey.value}
});
let encIV = encForm.createTextBox({
let encManualSalt = encForm.createCheckBox({
label: "Use fixed salt instead of random",
advanced: true
});
let encKey = encForm.createMediumTextBox({
label: "Key",
dataType: "b64",
advanced: true,
enabled: false,
enabledFunc: function() {return encManualKey.value}
});
let encManualKey = encForm.createCheckBox({
label: "Use fixed key instead of password",
advanced: true
});
let encIV = encForm.createMediumTextBox({
label: "IV",
dataType: "b64",
advanced: true,
disabled: true
enabledFunc: function() {return encManualIV.value}
});
let encManualIV = encForm.createCheckBox({
label: "Use fixed IV instead of random",
advanced: true
});
let encButton = encForm.createButton({label: "Encrypt"});
let encOut = encForm.createOutput({
@ -39,7 +58,6 @@ let decPass = decForm.createPasswordInput({label: "Password"});
let decButton = decForm.createButton({label: "Decrypt"});
let decOut = decForm.createOutput({label: "Output"});
function getKeyMaterial(password) {
let enc = new TextEncoder();
return window.crypto.subtle.importKey(
@ -69,14 +87,38 @@ function getKey(keyMaterial, salt) {
);
}
async function encrypt() {
let keyMaterial = await getKeyMaterial(encPass.value);
let salt = window.crypto.getRandomValues(new Uint8Array(16));
encSalt.value = salt;
let key = await getKey(keyMaterial, salt);
encButton.handle.addEventListener("click", async function() {
let iv = window.crypto.getRandomValues(new Uint8Array(16));
encIV.value = iv;
let salt;
if (encSalt.enabledFunc()) {
salt = encSalt.value;
} else {
salt = window.crypto.getRandomValues(new Uint8Array(16));
encSalt.value = salt;
}
let keyMaterial = await getKeyMaterial(encPass.value);
let key;
if (encManualKey.value) {
key = await window.crypto.subtle.importKey(
"raw",
encKey.value,
{"name": "AES-GCM"},
true,
["encrypt", "decrypt"]
);
} else {
key = await getKey(keyMaterial, salt);
encKey.value = await window.crypto.subtle.exportKey("raw", key);
}
let iv;
if (encManualIV.value) {
iv = encIV.value;
} else {
iv = window.crypto.getRandomValues(new Uint8Array(16));
encIV.value = iv;
}
let enc = new TextEncoder();
let msgEncoded = enc.encode(encMsg.value);
@ -97,9 +139,9 @@ async function encrypt() {
"salt": bufToB64(salt),
"iv": bufToB64(iv)
}
}
});
async function decrypt() {
decButton.handle.addEventListener("click", async function() {
let msgEncoded = decMsg.value;
let ciphertext, iv, salt;
@ -135,7 +177,4 @@ async function decrypt() {
let dec = new TextDecoder();
decOut.value = `${dec.decode(plaintext)}`;
}
encButton.handle.addEventListener("click", encrypt);
decButton.handle.addEventListener("click", decrypt);
});

View File

@ -1,12 +1,18 @@
class InterfaceElement {
rootNodes = [];
constructor({fragment}) {
constructor({fragment, enabledFunc}) {
if (fragment === undefined) {
this.fragment = new DocumentFragment();
} else {
this.fragment = fragment;
}
if (enabledFunc === undefined) {
this.enabledFunc = function(){ return true; };
} else {
this.enabledFunc = enabledFunc;
}
}
scanNodes() {
@ -34,6 +40,15 @@ class InterfaceElement {
if (this.hidden === true) this.clearAlerts();
}
#enabled = true;
get enabled() {
return this.#enabled;
}
set enabled(x) {
this.#enabled = x;
this.handle.disabled = !this.#enabled;
}
}
function dataTypeSupports(params, validTypes) {
@ -59,6 +74,7 @@ class Form extends InterfaceElement {
let labelTag = document.createElement("h2");
labelTag.appendChild(document.createTextNode(label));
this.fragment.appendChild(labelTag);
this.rootNodes.push(labelTag);
}
this.fragment.appendChild(this.handle);
@ -100,6 +116,7 @@ class Form extends InterfaceElement {
appendElement(elem) {
elem.mount(this.handle);
this.elements.push(elem);
this.rootNodes.push(...elem.rootNodes);
if (elem.advanced) {
elem.hidden = !this.advanced;
}
@ -154,6 +171,11 @@ class Form extends InterfaceElement {
li.appendChild(params.tag);
li.appendChild(params.labelTag);
dataTypeSupports(params, ["bool"]);
params.tag.addEventListener("change", function() {
for (const elem of this.elements) {
elem.enabled = elem.enabledFunc();
}
}.bind(this));
return this.appendElement(new FormElement(params));
}
@ -185,17 +207,8 @@ function bufToB64 (buf) {
}
class FormElement extends InterfaceElement {
#enabled = true;
get enabled() {
return this.#enabled;
}
set enabled(x) {
this.#enabled = x;
this.handle.disabled = !this.#enabled;
}
constructor({tag, labelTag, label="", fragment, dataType, advanced=false, enabled=true}) {
super({fragment});
constructor({tag, labelTag, label="", fragment, dataType, advanced=false, enabled=true, enabledFunc}) {
super({fragment, enabled, enabledFunc});
this.labelText = label;
if (labelTag === undefined) {
@ -211,7 +224,6 @@ class FormElement extends InterfaceElement {
this.handle = tag;
this.dataType = dataType;
this.enabled = enabled;
this.advanced = advanced;
if (this.advanced === true) this.hidden = true;