add basic aes prototype
This commit is contained in:
parent
45964ecf70
commit
97b34b2a56
21
aes.html
Normal file
21
aes.html
Normal 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>
|
127
encryption.js
127
encryption.js
@ -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
140
scripts/aes.js
Normal 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);
|
@ -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);
|
|
@ -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>
|
|
Loading…
Reference in New Issue
Block a user