Initial prototype
This commit is contained in:
commit
48e562c936
23
dec.html
Normal file
23
dec.html
Normal 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
23
enc.html
Normal 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
125
encryption.js
Normal 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
82
style.css
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user