add basic aes prototype

This commit is contained in:
dogeystamp 2022-12-31 22:06:13 -05:00
parent 45964ecf70
commit 97b34b2a56
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38
5 changed files with 161 additions and 201 deletions

21
aes.html Normal file
View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Easy to use and simple online tool for AES encryption and decryption.
Advanced settings allow control over the IV, AES mode, and PBKDF2 parameters.">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>encryptme: Simple AES encryption/decryption</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>encryptme</h1>
<h2>Encryption</h2>
<div id="encryption"></div>
<h2>Decryption</h2>
<div id="decryption"></div>
<script src="scripts/interface.js"></script>
<script src="scripts/aes.js"></script>
</body>
</html>

View File

@ -1,127 +0,0 @@
function getMsg() {
return msg = document.getElementById("msg").value;
}
function getMsgEncoding () {
let enc = new TextEncoder();
return enc.encode(getMsg());
}
function getKeyMaterial () {
let pass = document.getElementById("password").value;
let enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(pass),
"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"]
);
}
function bufTo64 (buf) {
let bytes = new Uint8Array(buf);
let ascii = ''
for (var i = 0; i < bytes.byteLength; i++) {
ascii += String.fromCharCode(bytes[i]);
}
return btoa(ascii);
}
function b64ToBuf (b64) {
let ascii = atob(b64);
let buf = new ArrayBuffer(ascii.length);
let bytes = new Uint8Array(buf);
for (var i = 0; i < ascii.length; i++) {
bytes[i] = ascii.charCodeAt(i);
}
return buf;
}
function concatBuf(buf1, buf2) {
let tmp = new Uint8Array(buf1.byteLength + buf2.byteLength);
tmp.set(new Uint8Array(buf1), 0);
tmp.set(new Uint8Array(buf2), buf1.byteLength);
return tmp.buffer;
}
async function exportKey (key) {
let k = await window.crypto.subtle.exportKey("raw", key);
return bufTo64(k);
}
async function enc () {
outBox = document.getElementById("ciphertext");
outBox.innerHTML = '';
let keyMaterial = await getKeyMaterial();
let salt = window.crypto.getRandomValues(new Uint8Array(16));
let key = await getKey(keyMaterial, salt);
let iv = window.crypto.getRandomValues(new Uint8Array(16));
let msgEncoded = getMsgEncoding();
ciphertext = await window.crypto.subtle.encrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
msgEncoded
);
let output = {
"ciphertext": bufTo64(ciphertext),
"salt": bufTo64(salt),
"iv": bufTo64(iv)
}
outBox.innerHTML = `${btoa(JSON.stringify(output))}`;
}
async function dec () {
outBox = document.getElementById("plaintext");
outBox.innerHTML = '';
let msgEncoded = JSON.parse(atob(getMsg()));
let ciphertext = new b64ToBuf(msgEncoded.ciphertext);
let iv = new Uint8Array(b64ToBuf(msgEncoded.iv));
let salt = new Uint8Array(b64ToBuf(msgEncoded.salt));
let keyMaterial = await getKeyMaterial();
let key = await getKey(keyMaterial, salt);
try {
let plaintext = await window.crypto.subtle.decrypt(
{
"name": "AES-GCM",
"iv": iv
},
key,
ciphertext
);
let dec = new TextDecoder();
outBox.innerHTML = `${dec.decode(plaintext)}`;
} catch (e) {
window.alert("Decryption error: incorrect password?");
}
}

140
scripts/aes.js Normal file
View File

@ -0,0 +1,140 @@
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) {
window.alert("Decryption error: incorrect password?");
}
let dec = new TextDecoder();
decOut.value = `${dec.decode(plaintext)}`;
}
encButton.handle.addEventListener("click", encrypt);
decButton.handle.addEventListener("click", decrypt);

View File

@ -1,59 +0,0 @@
let form = new Form({id: "encryption"});
document.body.appendChild(form.handle);
let inp = new FormElement({
id: "textbox",
type: "textbox",
label: "Text box",
form: form
});
let inp2 = new FormElement({
id: "password",
type: "password",
label: "Password",
form: form
});
let inp3 = new FormElement({
id: "textarea",
type: "textarea",
label: "Large text box",
enabled: true,
dataType: "b64",
form: form
});
let inp4 = new FormElement({
id: "textarea",
type: "textarea",
label: "Large text box (disabled)",
enabled: false,
form: form
});
let out = new FormElement({
id: "output",
type: "output",
label: "Output box",
dataType: "b64",
form: form
});
let button = new FormElement({
id: "button",
type: "button",
label: "Do things",
form: form
});
let outAdvanced = new FormElement({
id: "output-advanced",
type: "output",
label: "Output box (advanced setting)",
advanced: true,
form: form
});
inp.alertBox("alert-info", "Pater noster qui es in caelo sanctificetur nomen tuum adveniat regnum tuum.");
button.handle.addEventListener("click", form.clearAlerts);

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>encryptme: interface logic testing page</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>encryptme</h1>
<script src="scripts/interface.js"></script>
<script src="scripts/testpage.js"></script>
</body>
</html>