| 120 | * Decrypt data using AES-256-GCM with the data encryption key |
| 121 | */ |
| 122 | export function decryptWithDataKey(bundle: Uint8Array, dataKey: Uint8Array): any | null { |
| 123 | if (bundle.length < 1) return null; |
| 124 | if (bundle[0] !== 0) return null; |
| 125 | if (bundle.length < 12 + 16 + 1) return null; |
| 126 | |
| 127 | const nonce = bundle.slice(1, 13); |
| 128 | const authTag = bundle.slice(bundle.length - 16); |
| 129 | const ciphertext = bundle.slice(13, bundle.length - 16); |
| 130 | |
| 131 | try { |
| 132 | const decipher = createDecipheriv('aes-256-gcm', dataKey, nonce); |
| 133 | decipher.setAuthTag(authTag); |
| 134 | |
| 135 | const decrypted = Buffer.concat([ |
| 136 | decipher.update(ciphertext), |
| 137 | decipher.final() |
| 138 | ]); |
| 139 | |
| 140 | return JSON.parse(new TextDecoder().decode(decrypted)); |
| 141 | } catch (error) { |
| 142 | return null; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | export function encrypt(key: Uint8Array, variant: 'legacy' | 'dataKey', data: any): Uint8Array { |
| 147 | if (variant === 'legacy') { |