/** * AriaEngine Crypto — 页面级 AES-GCM 加密 * @module engine/aria/crypto * * 使用 Web Crypto API (SubtleCrypto) 进行 AES-256-GCM 加密。 */ const ALGO = 'AES-GCM'; const IV_LENGTH = 12; let cryptoKey: CryptoKey | null = null; let enabled = false; export async function initCrypto(password: string, salt?: Uint8Array): Promise { const enc = new TextEncoder(); const keyMaterial = await crypto.subtle.importKey( 'raw', enc.encode(password), 'PBKDF2', false, ['deriveKey'], ); const actualSalt: any = salt || crypto.getRandomValues(new Uint8Array(16)); cryptoKey = await crypto.subtle.deriveKey( { name: 'PBKDF2', salt: actualSalt, iterations: 100000, hash: 'SHA-256' } as any, keyMaterial, { name: ALGO, length: 256 } as any, false, ['encrypt', 'decrypt'], ); enabled = true; return actualSalt as Uint8Array; } export function isCryptoEnabled(): boolean { return enabled; } export async function encryptPage(data: ArrayBuffer): Promise<{ iv: Uint8Array; data: ArrayBuffer }> { if (!cryptoKey) throw new Error('Crypto not initialized'); const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH)) as any; const ciphertext = await crypto.subtle.encrypt({ name: ALGO, iv } as any, cryptoKey, data); return { iv: iv as Uint8Array, data: ciphertext }; } export async function decryptPage(iv: Uint8Array, data: ArrayBuffer): Promise { if (!cryptoKey) throw new Error('Crypto not initialized'); return crypto.subtle.decrypt({ name: ALGO, iv } as any, cryptoKey, data); } export function closeCrypto(): void { cryptoKey = null; enabled = false; }