import { hexToString, stringToHex } from '.' const ENCRYPTION_ALGO_NAME = 'AES-GCM' export const generateEncryptionKey = async () => { const cryptoKey = await window.crypto.subtle.generateKey( { name: ENCRYPTION_ALGO_NAME, length: 128 }, true, ['encrypt', 'decrypt'] ) const key = await window.crypto.subtle.exportKey('jwk', cryptoKey) const jsonString = JSON.stringify(key) const hexKey = stringToHex(jsonString) const iv = new TextDecoder().decode( window.crypto.getRandomValues(new Uint8Array(16)) ) return `${hexKey}?iv=${iv}` } export const importKey = async (key: string) => { const splittedKey = key.split('?iv=') const keyString = hexToString(splittedKey[0]) const jsonWebKey = JSON.parse(keyString) const iv = new TextEncoder().encode(splittedKey[1]) const cryptoKey = await window.crypto.subtle.importKey( 'jwk', jsonWebKey, { name: ENCRYPTION_ALGO_NAME }, true, ['encrypt', 'decrypt'] ) return { cryptoKey, iv } } export const encryptArrayBuffer = async ( arrayBuffer: ArrayBuffer, key: string ) => { const { cryptoKey, iv } = await importKey(key) // Encrypt the data const encryptedData = await window.crypto.subtle.encrypt( { name: ENCRYPTION_ALGO_NAME, iv }, cryptoKey, arrayBuffer ) return encryptedData } export const decryptArrayBuffer = async ( encryptedData: ArrayBuffer, key: string ) => { const { cryptoKey, iv } = await importKey(key) // Decrypt the data const decryptedData = await window.crypto.subtle.decrypt( { name: ENCRYPTION_ALGO_NAME, iv }, cryptoKey, encryptedData ) return decryptedData }