sigit.io/src/utils/crypto.ts

82 lines
1.8 KiB
TypeScript
Raw Normal View History

import {
hexStringToUint8Array,
hexToString,
stringToHex,
uint8ArrayToHexString
} from '.'
2024-05-14 14:48:09 +00:00
import { DecryptionError } from '../types/errors/DecryptionError'
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 = uint8ArrayToHexString(
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 = hexStringToUint8Array(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
) => {
2024-05-14 14:48:09 +00:00
try {
const { cryptoKey, iv } = await importKey(key)
2024-05-15 08:50:21 +00:00
2024-05-14 14:48:09 +00:00
// Decrypt the data
const decryptedData = await window.crypto.subtle.decrypt(
{ name: ENCRYPTION_ALGO_NAME, iv },
cryptoKey,
encryptedData
)
2024-05-15 08:50:21 +00:00
2024-05-14 14:48:09 +00:00
return decryptedData
} catch (err) {
throw new DecryptionError(err)
}
}