added manual salt, IV and key options
This commit is contained in:
parent
45910aedfb
commit
f49f072fab
@ -1,22 +1,41 @@
|
|||||||
let encForm = new Form({label: "Encryption"});
|
let encForm = new Form({label: "Encryption"});
|
||||||
|
|
||||||
let encMsg = encForm.createTextArea({label: "Message"});
|
let encMsg = encForm.createTextArea({label: "Message"});
|
||||||
let encPass = encForm.createPasswordInput({label: "Password"});
|
let encPass = encForm.createPasswordInput({
|
||||||
let encManualMode = encForm.createCheckBox({
|
label: "Password",
|
||||||
label: "Manual mode",
|
enabledFunc: function() {return !encManualKey.value}
|
||||||
advanced: true
|
|
||||||
});
|
});
|
||||||
let encSalt = encForm.createTextBox({
|
let encSalt = encForm.createMediumTextBox({
|
||||||
label: "PBKDF2 salt",
|
label: "PBKDF2 salt",
|
||||||
dataType: "b64",
|
dataType: "b64",
|
||||||
advanced: true,
|
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",
|
label: "IV",
|
||||||
dataType: "b64",
|
dataType: "b64",
|
||||||
advanced: true,
|
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 encButton = encForm.createButton({label: "Encrypt"});
|
||||||
let encOut = encForm.createOutput({
|
let encOut = encForm.createOutput({
|
||||||
@ -39,7 +58,6 @@ let decPass = decForm.createPasswordInput({label: "Password"});
|
|||||||
let decButton = decForm.createButton({label: "Decrypt"});
|
let decButton = decForm.createButton({label: "Decrypt"});
|
||||||
let decOut = decForm.createOutput({label: "Output"});
|
let decOut = decForm.createOutput({label: "Output"});
|
||||||
|
|
||||||
|
|
||||||
function getKeyMaterial(password) {
|
function getKeyMaterial(password) {
|
||||||
let enc = new TextEncoder();
|
let enc = new TextEncoder();
|
||||||
return window.crypto.subtle.importKey(
|
return window.crypto.subtle.importKey(
|
||||||
@ -69,14 +87,38 @@ function getKey(keyMaterial, salt) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function encrypt() {
|
encButton.handle.addEventListener("click", async function() {
|
||||||
let keyMaterial = await getKeyMaterial(encPass.value);
|
|
||||||
let salt = window.crypto.getRandomValues(new Uint8Array(16));
|
|
||||||
encSalt.value = salt;
|
|
||||||
let key = await getKey(keyMaterial, salt);
|
|
||||||
|
|
||||||
let iv = window.crypto.getRandomValues(new Uint8Array(16));
|
let salt;
|
||||||
encIV.value = iv;
|
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 enc = new TextEncoder();
|
||||||
let msgEncoded = enc.encode(encMsg.value);
|
let msgEncoded = enc.encode(encMsg.value);
|
||||||
@ -97,9 +139,9 @@ async function encrypt() {
|
|||||||
"salt": bufToB64(salt),
|
"salt": bufToB64(salt),
|
||||||
"iv": bufToB64(iv)
|
"iv": bufToB64(iv)
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
async function decrypt() {
|
decButton.handle.addEventListener("click", async function() {
|
||||||
let msgEncoded = decMsg.value;
|
let msgEncoded = decMsg.value;
|
||||||
|
|
||||||
let ciphertext, iv, salt;
|
let ciphertext, iv, salt;
|
||||||
@ -135,7 +177,4 @@ async function decrypt() {
|
|||||||
|
|
||||||
let dec = new TextDecoder();
|
let dec = new TextDecoder();
|
||||||
decOut.value = `${dec.decode(plaintext)}`;
|
decOut.value = `${dec.decode(plaintext)}`;
|
||||||
}
|
});
|
||||||
|
|
||||||
encButton.handle.addEventListener("click", encrypt);
|
|
||||||
decButton.handle.addEventListener("click", decrypt);
|
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
class InterfaceElement {
|
class InterfaceElement {
|
||||||
rootNodes = [];
|
rootNodes = [];
|
||||||
|
|
||||||
constructor({fragment}) {
|
constructor({fragment, enabledFunc}) {
|
||||||
if (fragment === undefined) {
|
if (fragment === undefined) {
|
||||||
this.fragment = new DocumentFragment();
|
this.fragment = new DocumentFragment();
|
||||||
} else {
|
} else {
|
||||||
this.fragment = fragment;
|
this.fragment = fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enabledFunc === undefined) {
|
||||||
|
this.enabledFunc = function(){ return true; };
|
||||||
|
} else {
|
||||||
|
this.enabledFunc = enabledFunc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scanNodes() {
|
scanNodes() {
|
||||||
@ -34,6 +40,15 @@ class InterfaceElement {
|
|||||||
|
|
||||||
if (this.hidden === true) this.clearAlerts();
|
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) {
|
function dataTypeSupports(params, validTypes) {
|
||||||
@ -59,6 +74,7 @@ class Form extends InterfaceElement {
|
|||||||
let labelTag = document.createElement("h2");
|
let labelTag = document.createElement("h2");
|
||||||
labelTag.appendChild(document.createTextNode(label));
|
labelTag.appendChild(document.createTextNode(label));
|
||||||
this.fragment.appendChild(labelTag);
|
this.fragment.appendChild(labelTag);
|
||||||
|
this.rootNodes.push(labelTag);
|
||||||
}
|
}
|
||||||
this.fragment.appendChild(this.handle);
|
this.fragment.appendChild(this.handle);
|
||||||
|
|
||||||
@ -100,6 +116,7 @@ class Form extends InterfaceElement {
|
|||||||
appendElement(elem) {
|
appendElement(elem) {
|
||||||
elem.mount(this.handle);
|
elem.mount(this.handle);
|
||||||
this.elements.push(elem);
|
this.elements.push(elem);
|
||||||
|
this.rootNodes.push(...elem.rootNodes);
|
||||||
if (elem.advanced) {
|
if (elem.advanced) {
|
||||||
elem.hidden = !this.advanced;
|
elem.hidden = !this.advanced;
|
||||||
}
|
}
|
||||||
@ -154,6 +171,11 @@ class Form extends InterfaceElement {
|
|||||||
li.appendChild(params.tag);
|
li.appendChild(params.tag);
|
||||||
li.appendChild(params.labelTag);
|
li.appendChild(params.labelTag);
|
||||||
dataTypeSupports(params, ["bool"]);
|
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));
|
return this.appendElement(new FormElement(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,17 +207,8 @@ function bufToB64 (buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FormElement extends InterfaceElement {
|
class FormElement extends InterfaceElement {
|
||||||
#enabled = true;
|
constructor({tag, labelTag, label="", fragment, dataType, advanced=false, enabled=true, enabledFunc}) {
|
||||||
get enabled() {
|
super({fragment, enabled, enabledFunc});
|
||||||
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});
|
|
||||||
|
|
||||||
this.labelText = label;
|
this.labelText = label;
|
||||||
if (labelTag === undefined) {
|
if (labelTag === undefined) {
|
||||||
@ -211,7 +224,6 @@ class FormElement extends InterfaceElement {
|
|||||||
|
|
||||||
this.handle = tag;
|
this.handle = tag;
|
||||||
this.dataType = dataType;
|
this.dataType = dataType;
|
||||||
this.enabled = enabled;
|
|
||||||
this.advanced = advanced;
|
this.advanced = advanced;
|
||||||
|
|
||||||
if (this.advanced === true) this.hidden = true;
|
if (this.advanced === true) this.hidden = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user