Initial prototype

This commit is contained in:
dogeystamp 2022-12-28 19:04:46 -05:00
commit 48e562c936
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38
4 changed files with 253 additions and 0 deletions

23
dec.html Normal file
View File

@ -0,0 +1,23 @@
<!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: Decryption</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="encryption.js"></script>
<h1>encryptme</h1>
<label for="msg">Ciphertext: </label>
<textarea id="msg" form="form"></textarea>
<label for="password">Password: </label>
<input id="password" type="password">
<button id="decrypt">Decrypt</button>
<textarea id="plaintext"></textarea>
<script>
document.getElementById("decrypt").addEventListener("click", dec);
</script>
</body>
</html>

23
enc.html Normal file
View File

@ -0,0 +1,23 @@
<!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: Encryption</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="encryption.js"></script>
<h1>encryptme</h1>
<label for="msg">Message: </label>
<textarea id="msg" form="form"></textarea>
<label for="password">Password: </label>
<input id="password" type="password">
<button id="encrypt">Encrypt</button>
<textarea id="ciphertext"></textarea>
<script>
document.getElementById("encrypt").addEventListener("click", enc);
</script>
</body>
</html>

125
encryption.js Normal file
View File

@ -0,0 +1,125 @@
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");
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 = concatBuf(concatBuf(ciphertext, salt), iv);
outBox.innerHTML = `${bufTo64(output)}`;
let keyExp = await exportKey (key);
window.alert(bufTo64(iv));
}
async function dec () {
outBox = document.getElementById("plaintext");
outBox.innerHTML = '';
let msgEncoded = b64ToBuf(getMsg());
let ciphertext = new Uint8Array(msgEncoded.slice(0, -32));
let iv = new Uint8Array(msgEncoded.slice(-16));
let salt = new Uint8Array(msgEncoded.slice(-32, -16));
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(e.name);
}
}

82
style.css Normal file
View File

@ -0,0 +1,82 @@
body {
max-width: 650px;
margin: 40px auto;
padding: 0 10px;
color: #444444;
background: #eeeeee;
}
h1, h2, h3, h4, h5, h6 {
color: #666666;
}
body, button {
font: 18px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
textarea {
width: 100%;
height: 15em;
padding-top: 1em;
resize: none;
}
label, input, button, textarea {
display: block;
margin-top: 1em;
border: none;
border-radius: 5px;
transition-duration: 0.2s;
}
input, textarea, button {
border: 1px solid #44444444;
}
input:focus, textarea:focus, button:focus {
outline: none;
}
input:focus, textarea:focus {
border: 1px solid #444444aa;
}
p {
text-align: justify;
}
button {
transition-duration: 0.05s;
border: 1px solid #44444444;
}
button:hover {
border: 1px solid #444444aa;
}
button:active {
opacity: 50%;
}
@media (prefers-color-scheme: dark) {
body {
color: #c9d1d9;
background: #0d1117;
}
h1, h2, h3, h4, h5, h6 {
color: #c9d1d9;
}
a:link {
color: #58a6ff;
}
a:visited {
color: #8e96f0;
}
textarea, input, button {
background: #1d2127;
color: #c9d1d9;
}
}