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'
Create a free account and build your private vault. Share publicly whenever you want.