Skip to content

Instantly share code, notes, and snippets.

@likev
Created December 23, 2021 15:40
Show Gist options
  • Save likev/6f82a4109a0001160aefd59ea050ea70 to your computer and use it in GitHub Desktop.
Save likev/6f82a4109a0001160aefd59ea050ea70 to your computer and use it in GitHub Desktop.
AES-GCM encrypt decrypt and download
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AES-GCM encrypt decrypt and download</title>
</head>
<body id='app'>
<a href="#" id=download download="test.json.encrypt">Download</a>
<script>
console.log('start')
async function AES_GCM_create(password, salt, iv) {
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
//let password = window.prompt("Enter your password");
let enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
"PBKDF2",
false,
["deriveBits", "deriveKey"]
);
}
let keyMaterial = await getKeyMaterial();
let key = await window.crypto.subtle.deriveKey(
{
"name": "PBKDF2",
salt,
"iterations": 100000,
"hash": "SHA-256"
},
keyMaterial,
{ "name": "AES-GCM", "length": 256 },
true,
["encrypt", "decrypt"]
);
async function encrypt(plaintext) {
return window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv
},
key,
plaintext
);
}
async function decrypt(ciphertext) {
return window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv
},
key,
ciphertext
);
}
return {
encrypt,
decrypt
};
}
async function test_encrypt_decrypt_download() {
/*
const salt = window.crypto.getRandomValues(new Uint8Array(16));
const iv = window.crypto.getRandomValues(new Uint8Array(12));
*/
const { salt, iv } = {
"salt": Uint8Array.from([82, 194, 71, 248, 178, 166, 144, 68, 79, 133, 255, 214, 65, 227, 25, 167]),
"iv": Uint8Array.from([44, 43, 196, 97, 249, 56, 62, 30, 71, 21, 135, 76])
}
console.log({
salt: JSON.stringify([...salt]),
iv: JSON.stringify([...iv])
})
const aes_gcm = await AES_GCM_create('password', salt, iv);
const plaintext = JSON.stringify({
"name": "John Doe",
"age": 42,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" }
]
});
const ciphertext = await aes_gcm.encrypt(new TextEncoder().encode(plaintext));
const download = document.getElementById('download');
download.href = URL.createObjectURL(new Blob([ciphertext], { type: 'application/octet-stream' }));
const decrypted = await aes_gcm.decrypt(ciphertext);
console.log(new TextDecoder().decode(decrypted));
}
test_encrypt_decrypt_download();
async function test_decrypt_file() {
const { salt, iv } = {
"salt": Uint8Array.from([82, 194, 71, 248, 178, 166, 144, 68, 79, 133, 255, 214, 65, 227, 25, 167]),
"iv": Uint8Array.from([44, 43, 196, 97, 249, 56, 62, 30, 71, 21, 135, 76])
}
console.log(salt)
const aes_gcm = await AES_GCM_create('password', salt, iv);
const test_json = await fetch('test.json.encrypt')
.then(res => res.arrayBuffer())
.then(ciphertext => aes_gcm.decrypt(ciphertext))
.then(decrypted => new TextDecoder().decode(decrypted))
console.log(test_json)
}
test_decrypt_file()
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment