function getKeyMaterial() { const password = window.prompt("Enter your password"); const enc = new TextEncoder(); return window.crypto.subtle.importKey( "raw", enc.encode(password), "PBKDF2", false, ["deriveBits", "deriveKey"] ); } async function encrypt(plaintext, salt, iv) { const keyMaterial = await getKeyMaterial(); const key = await window.crypto.subtle.deriveKey( { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256", }, keyMaterial, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"] ); console.log(typeof plaintext); const enc = new TextEncoder(); plaintext = enc.encode(plaintext); console.log(typeof plaintext); console.log(typeof iv); console.log(iv); return window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, plaintext); } async function decrypt(ciphertext, salt, iv) { try { console.log(ciphertext); let keyMaterial = await getKeyMaterial(); const key = await window.crypto.subtle.deriveKey( { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256", }, keyMaterial, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"] ); let decrypted = await window.crypto.subtle.decrypt( { name: "AES-GCM", iv: iv, }, key, ciphertext ); let dec = new TextDecoder(); return dec.decode(decrypted); } catch (e) { return null; } } const salt = window.crypto.getRandomValues(new Uint8Array(16)); const iv = window.crypto.getRandomValues(new Uint8Array(12)); encrypt("Hello World", salt, iv).then( (ciphertext) => { console.log(ciphertext); decrypt(ciphertext, salt, iv).then( (plaintext) => { console.log(plaintext); } ); } );