aes.js: added CBC mode

This commit is contained in:
dogeystamp 2023-01-26 22:02:18 -05:00
parent 7ed8cc7e3a
commit 0e0ac98c84
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38

View File

@ -66,9 +66,13 @@ let encMode = encForm.createDropDown({
advanced: true, advanced: true,
options: [ options: [
{ {
name: "AES-GCM", name: "AES-GCM (Galois/Counter Mode)",
value: "AES-GCM" value: "AES-GCM"
}, },
{
name: "AES-CBC (Cipher Block Chaining)",
value: "AES-CBC"
},
] ]
}); });
let encButton = encForm.createButton({label: "Encrypt"}); let encButton = encForm.createButton({label: "Encrypt"});
@ -117,7 +121,7 @@ function getKeyMaterial(password) {
); );
} }
function getKey(keyMaterial, salt, pbkdf2Iters) { function getKey(keyMaterial, salt, pbkdf2Iters, encMode) {
return window.crypto.subtle.deriveKey( return window.crypto.subtle.deriveKey(
{ {
"name": "PBKDF2", "name": "PBKDF2",
@ -127,7 +131,7 @@ function getKey(keyMaterial, salt, pbkdf2Iters) {
}, },
keyMaterial, keyMaterial,
{ {
"name": "AES-GCM", "name": encMode,
"length": 256 "length": 256
}, },
true, true,
@ -145,6 +149,16 @@ async function aesGcmEnc(key, iv, msgEncoded) {
msgEncoded msgEncoded
); );
} }
async function aesCbcEnc(key, iv, msgEncoded) {
return window.crypto.subtle.encrypt(
{
"name": "AES-CBC",
"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);
@ -173,7 +187,7 @@ encButton.handle.addEventListener("click", async function() {
encSalt.value = salt; encSalt.value = salt;
} }
key = await getKey(keyMaterial, salt, pbkdf2Iters); key = await getKey(keyMaterial, salt, pbkdf2Iters, encMode.value);
encKey.value = await window.crypto.subtle.exportKey("raw", key); encKey.value = await window.crypto.subtle.exportKey("raw", key);
} }
@ -188,7 +202,19 @@ 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 aesGcmEnc(key, iv, msgEncoded); let ciphertext;
switch (encMode.value) {
case "AES-GCM":
ciphertext = await aesGcmEnc(key, iv, msgEncoded);
break;
case "AES-CBC":
ciphertext = await aesCbcEnc(key, iv, msgEncoded);
break;
default:
let e = Error(`Mode '${encMode.value}' is not implemented.`);
encMode.handleError(e);
return;
}
encOutRaw.value = ciphertext; encOutRaw.value = ciphertext;
@ -211,6 +237,16 @@ async function aesGcmDec(key, iv, ciphertext) {
ciphertext ciphertext
); );
} }
async function aesCbcDec(key, iv, ciphertext) {
return window.crypto.subtle.decrypt(
{
"name": "AES-CBC",
"iv": iv
},
key,
ciphertext
);
}
decButton.handle.addEventListener("click", async function() { decButton.handle.addEventListener("click", async function() {
let msgEncoded = decMsg.value; let msgEncoded = decMsg.value;
@ -254,15 +290,28 @@ decButton.handle.addEventListener("click", async function() {
decMsg.handleError(e); decMsg.handleError(e);
} }
} else { } else {
key = await getKey(keyMaterial, salt, pbkdf2Iters); key = await getKey(keyMaterial, salt, pbkdf2Iters, encMode);
} }
let plaintext; let plaintext;
try { try {
plaintext = await aesGcmDec(key, iv, ciphertext); switch (encMode) {
case "AES-GCM":
plaintext = await aesGcmDec(key, iv, ciphertext);
break;
case "AES-CBC":
plaintext = await aesCbcDec(key, iv, ciphertext);
break;
default:
throw Error(`Mode '${encMode.value}' is not implemented.`);
}
} catch (e) { } catch (e) {
decMsg.handleError(e, "Error during decryption."); if (e.message !== "" && e.message !== undefined) {
decMsg.handleError(e, "Error during decryption.");
} else {
decMsg.handleError(Error("Could not decrypt; is your password/key correct?"));
}
} }
let dec = new TextDecoder(); let dec = new TextDecoder();