Created
December 23, 2021 15:40
-
-
Save likev/6f82a4109a0001160aefd59ea050ea70 to your computer and use it in GitHub Desktop.
AES-GCM encrypt decrypt and download
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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