// Created on savesnippets.com ยท https://savesnippets.com/iyO8qa2dXndY5c const enc = new TextEncoder(); const dec = new TextDecoder(); async function deriveKey(password) { const raw = await crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']); return crypto.subtle.deriveKey( { name: 'PBKDF2', salt: enc.encode('savesnippets-salt'), iterations: 100_000, hash: 'SHA-256' }, raw, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'] ); } async function encrypt(plaintext, password) { const key = await deriveKey(password); const iv = crypto.getRandomValues(new Uint8Array(12)); const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, enc.encode(plaintext)); const out = new Uint8Array(iv.byteLength + ct.byteLength); out.set(iv); out.set(new Uint8Array(ct), iv.byteLength); return btoa(String.fromCharCode(...out)); } async function decrypt(ciphertext, password) { const key = await deriveKey(password); const data = Uint8Array.from(atob(ciphertext), (c) => c.charCodeAt(0)); const iv = data.slice(0, 12); const ct = data.slice(12); const pt = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct); return dec.decode(pt); } // Usage const token = await encrypt('super secret', 'myPassword'); console.log(await decrypt(token, 'myPassword')); // 'super secret'