// Encrypts data using AES-GCM
async function encryptData(data: string, key: CryptoKey) {
const encoder = new TextEncoder();
const iv = crypto.getRandomValues(new Uint8Array(12)); // Initialization Vector
const encrypted = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
encoder.encode(data),
);
return { encrypted, iv };
}
// Decrypts data using AES-GCM
async function decryptData(
encrypted: ArrayBuffer,
iv: Uint8Array,
key: CryptoKey,
) {
const decrypted = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
encrypted,
);
const decoder = new TextDecoder();
return decoder.decode(decrypted);
}
async function generateKeyString(): Promise<string> {
try {
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256,
},
true,
["encrypt", "decrypt"],
);
const exportedKey = await crypto.subtle.exportKey("jwk", key);
return JSON.stringify(exportedKey);
} catch (error) {
console.error("Error generating key:", error);
return "";
}
}
async function generateKeyFromString(
keyString: string,
): Promise<CryptoKey> {
const keyData = JSON.parse(keyString);
const key = await crypto.subtle.importKey(
"jwk",
keyData,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"],
);
return key;
}
// Example usage
async function example() {
const keyString = await generateKeyString();
const cryptoKey = await generateKeyFromString(keyString)!;
const stringToEncrypt = "Hello, world!";
const {
// Save the encrypted data and the IV to DB
encrypted,
iv,
} = await encryptData(stringToEncrypt, cryptoKey);
const decryptedMessage = await decryptData(encrypted, iv, cryptoKey);
console.log("Original:", stringToEncrypt);
console.log("Encrypted:", encrypted);
console.log("Decrypted:", decryptedMessage);
}
example();