aes.js: added CBC mode
This commit is contained in:
parent
7ed8cc7e3a
commit
0e0ac98c84
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user