encryptme/scripts/aes.js

141 lines
2.8 KiB
JavaScript

let encForm = new Form({id: "encryption", tag: document.getElementById("encryption")});
let encMsg = new FormElement({
id: "msg",
type: "textarea",
label: "Message",
form: encForm
});
let encPass = new FormElement({
id: "password",
type: "password",
label: "Password",
form: encForm
});
let encButton = new FormElement({
id: "button",
type: "button",
label: "Encrypt",
form: encForm
});
let encOut = new FormElement({
id: "output",
type: "output",
label: "Output",
dataType: "json-b64",
form: encForm
});
let decForm = new Form({id: "decryption", tag: document.getElementById("decryption")});
let decMsg = new FormElement({
id: "msg",
type: "textarea",
label: "Encrypted message",
dataType: "json-b64",
form: decForm
});
let decPass = new FormElement({
id: "password",
type: "password",
label: "Password",
form: decForm
});
let decButton = new FormElement({
id: "button",
type: "button",
label: "Decrypt",
form: decForm
});
let decOut = new FormElement({
id: "output",
type: "output",
label: "Output",
form: decForm
});
function getKeyMaterial(password) {
let enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
"PBKDF2",
false,
["deriveKey"]
);
}
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
"name": "PBKDF2",
"hash": "SHA-256",
"salt": salt,
"iterations": 300000
},
keyMaterial,
{
"name": "AES-GCM",
"length": 256
},
true,
["encrypt", "decrypt"]
);
}
async function encrypt() {
let keyMaterial = await getKeyMaterial(encPass.value);
let salt = window.crypto.getRandomValues(new Uint8Array(16));
let key = await getKey(keyMaterial, salt);
let iv = window.crypto.getRandomValues(new Uint8Array(16));
let enc = new TextEncoder();
let msgEncoded = enc.encode(encMsg.value);
let ciphertext = await window.crypto.subtle.encrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
msgEncoded
);
encOut.value = {
"ciphertext": bufToB64(ciphertext),
"salt": bufToB64(salt),
"iv": bufToB64(iv)
}
}
async function decrypt() {
let msgEncoded = decMsg.value;
let ciphertext = new b64ToBuf(msgEncoded.ciphertext);
let iv = new Uint8Array(b64ToBuf(msgEncoded.iv));
let salt = new Uint8Array(b64ToBuf(msgEncoded.salt));
let keyMaterial = await getKeyMaterial(decPass.value);
let key = await getKey(keyMaterial, salt);
let plaintext;
try {
plaintext = await window.crypto.subtle.decrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
ciphertext
);
} catch (e) {
decPass.alertBox("alert-error", "Decryption error: incorrect password?");
}
let dec = new TextDecoder();
decOut.value = `${dec.decode(plaintext)}`;
}
encButton.handle.addEventListener("click", encrypt);
decButton.handle.addEventListener("click", decrypt);