aes.js: slight refactoring

preparing to implement other AES modes
This commit is contained in:
dogeystamp 2023-01-26 19:29:41 -05:00
parent 6972790053
commit 7ed8cc7e3a
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38

View File

@ -61,6 +61,16 @@ let encManualIV = encForm.createCheckBox({
label: "Use fixed IV instead of random", label: "Use fixed IV instead of random",
advanced: true advanced: true
}); });
let encMode = encForm.createDropDown({
label: "AES mode",
advanced: true,
options: [
{
name: "AES-GCM",
value: "AES-GCM"
},
]
});
let encButton = encForm.createButton({label: "Encrypt"}); let encButton = encForm.createButton({label: "Encrypt"});
let encOut = encForm.createOutput({ let encOut = encForm.createOutput({
label: "Output", label: "Output",
@ -125,6 +135,17 @@ function getKey(keyMaterial, salt, pbkdf2Iters) {
); );
} }
async function aesGcmEnc(key, iv, msgEncoded) {
return window.crypto.subtle.encrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
msgEncoded
);
}
encButton.handle.addEventListener("click", async function() { encButton.handle.addEventListener("click", async function() {
let keyMaterial = await getKeyMaterial(encPass.value); let keyMaterial = await getKeyMaterial(encPass.value);
let key; let key;
@ -140,7 +161,7 @@ encButton.handle.addEventListener("click", async function() {
key = await window.crypto.subtle.importKey( key = await window.crypto.subtle.importKey(
"raw", "raw",
encKey.value, encKey.value,
{"name": "AES-GCM"}, {"name": encMode.value},
true, true,
["encrypt", "decrypt"] ["encrypt", "decrypt"]
); );
@ -167,14 +188,7 @@ encButton.handle.addEventListener("click", async function() {
let enc = new TextEncoder(); let enc = new TextEncoder();
let msgEncoded = enc.encode(encMsg.value); let msgEncoded = enc.encode(encMsg.value);
let ciphertext = await window.crypto.subtle.encrypt( let ciphertext = await aesGcmEnc(key, iv, msgEncoded);
{
"name": "AES-GCM",
"iv": iv
},
key,
msgEncoded
);
encOutRaw.value = ciphertext; encOutRaw.value = ciphertext;
@ -182,26 +196,39 @@ encButton.handle.addEventListener("click", async function() {
"ciphertext": bufToB64(ciphertext), "ciphertext": bufToB64(ciphertext),
"salt": bufToB64(salt), "salt": bufToB64(salt),
"iv": bufToB64(iv), "iv": bufToB64(iv),
"pbkdf2Iters": pbkdf2Iters "encMode": encMode.value,
"pbkdf2Iters": pbkdf2Iters,
} }
}); });
async function aesGcmDec(key, iv, ciphertext) {
return window.crypto.subtle.decrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
ciphertext
);
}
decButton.handle.addEventListener("click", async function() { decButton.handle.addEventListener("click", async function() {
let msgEncoded = decMsg.value; let msgEncoded = decMsg.value;
let ciphertext, iv, salt, pbkdf2Iters; let ciphertext, iv, salt, encMode, pbkdf2Iters;
try { try {
ciphertext = new b64ToBuf(msgEncoded.ciphertext); ciphertext = new b64ToBuf(msgEncoded.ciphertext);
iv = new Uint8Array(b64ToBuf(msgEncoded.iv)); iv = new Uint8Array(b64ToBuf(msgEncoded.iv));
salt = new Uint8Array(b64ToBuf(msgEncoded.salt)); salt = new Uint8Array(b64ToBuf(msgEncoded.salt));
encMode = msgEncoded.encMode;
pbkdf2Iters = msgEncoded.pbkdf2Iters; pbkdf2Iters = msgEncoded.pbkdf2Iters;
if (pbkdf2Iters < 1 || pbkdf2Iters%1 !== 0) { if (pbkdf2Iters < 1 || pbkdf2Iters%1 !== 0) {
decMsg.alertBox("alert-error", "Invalid PBKDF2 iters setting."); throw Error(`Invalid PBKDF2 iterations setting: ${pbkdf2Iters}`);
} else if (pbkdf2Iters > 1000000) { } else if (pbkdf2Iters > 1000000) {
decMsg.alertBox("alert-info", `PBKDF2 is using ${pbkdf2Iters} iterations: this might take a long time...`); decMsg.alertBox("alert-info", `PBKDF2 is using ${pbkdf2Iters} iterations: this might take a long time...`);
} }
} catch (e) { } catch (e) {
decMsg.alertBox("alert-error", "Invalid encrypted payload."); decMsg.handleError(e, "Invalid encrypted payload.");
} }
if (ciphertext === undefined if (ciphertext === undefined
@ -215,13 +242,17 @@ decButton.handle.addEventListener("click", async function() {
let keyMaterial = await getKeyMaterial(decPass.value); let keyMaterial = await getKeyMaterial(decPass.value);
let key; let key;
if (decManualKey.value) { if (decManualKey.value) {
key = await window.crypto.subtle.importKey( try {
"raw", key = await window.crypto.subtle.importKey(
decKey.value, "raw",
{"name": "AES-GCM"}, decKey.value,
true, {"name": encMode},
["encrypt", "decrypt"] true,
); ["encrypt", "decrypt"]
);
} catch (e) {
decMsg.handleError(e);
}
} else { } else {
key = await getKey(keyMaterial, salt, pbkdf2Iters); key = await getKey(keyMaterial, salt, pbkdf2Iters);
} }
@ -229,16 +260,9 @@ decButton.handle.addEventListener("click", async function() {
let plaintext; let plaintext;
try { try {
plaintext = await window.crypto.subtle.decrypt( plaintext = await aesGcmDec(key, iv, ciphertext);
{
"name": "AES-GCM",
"iv": iv
},
key,
ciphertext
);
} catch (e) { } catch (e) {
decPass.alertBox("alert-error", "Decryption error: incorrect password?"); decMsg.handleError(e, "Error during decryption.");
} }
let dec = new TextDecoder(); let dec = new TextDecoder();