69 lines
1.8 KiB
JavaScript
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"]
|
|
);
|
|
}
|