pssecret-web/static/crypto.js

69 lines
1.8 KiB
JavaScript

export async function generateKey() {
return await window.crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
}
export async function encryptData(data, key) {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const encodedData = new TextEncoder().encode(data);
const encryptedData = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
},
key,
encodedData
);
const encryptedArray = new Uint8Array(encryptedData);
const resultArray = new Uint8Array(iv.length + encryptedArray.length);
resultArray.set(iv);
resultArray.set(encryptedArray, iv.length);
return btoa(String.fromCharCode(...resultArray));
}
export async function decryptData(encryptedData, key) {
try {
const data = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0));
const iv = data.slice(0, 12);
const ciphertext = data.slice(12);
const decrypted = await window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv
},
key,
ciphertext
);
return new TextDecoder().decode(decrypted);
} catch (error) {
console.error('Decryption failed:', error);
throw error;
}
}
export async function exportKey(key) {
const exported = await window.crypto.subtle.exportKey("raw", key);
return btoa(String.fromCharCode(...new Uint8Array(exported)));
}
export async function importKey(keyData) {
const keyBytes = Uint8Array.from(atob(keyData), c => c.charCodeAt(0));
return await window.crypto.subtle.importKey(
"raw",
keyBytes,
"AES-GCM",
true,
["encrypt", "decrypt"]
);
}