/** * AriaEngine CryptoManager 加解密测试 * @module tests/engine/aria-crypto * * v0.2.6 补强:此前仅验证实例化,现在验证真实的加解密往返一致性。 */ import { CryptoManager, initCrypto, encryptPage, decryptPage, closeCrypto, } from '../../src/engine/aria/crypto'; function toBytes(data: ArrayBuffer): number[] { return Array.from(new Uint8Array(data)); } describe('AriaEngine — CryptoManager', () => { test('加解密往返一致', async () => { const cm = new CryptoManager(); await cm.init('test-password'); expect(cm.enabled).toBe(true); const original = new TextEncoder().encode('sensitive row data').buffer; const { iv, data } = await cm.encryptPage(original); // 密文应为乱码(与原文不同) expect(toBytes(data)).not.toEqual(toBytes(original)); const decrypted = await cm.decryptPage(iv, data); expect(toBytes(decrypted)).toEqual(toBytes(original)); cm.close(); expect(cm.enabled).toBe(false); }); test('错误密码解密失败(密钥不同)', async () => { const cm1 = new CryptoManager(); await cm1.init('correct-password'); const original = new TextEncoder().encode('top secret').buffer; const { iv, data } = await cm1.encryptPage(original); const cm2 = new CryptoManager(); await cm2.init('wrong-password'); await expect(cm2.decryptPage(iv, data)).rejects.toThrow(); cm1.close(); cm2.close(); }); test('不同 salt 派生不同密钥,解密互相失败', async () => { const cm1 = new CryptoManager(); await cm1.init('pwd', new Uint8Array(16).fill(1)); const cm2 = new CryptoManager(); await cm2.init('pwd', new Uint8Array(16).fill(2)); const original = new TextEncoder().encode('salt matters').buffer; const { iv, data } = await cm1.encryptPage(original); await expect(cm2.decryptPage(iv, data)).rejects.toThrow(); cm1.close(); cm2.close(); }); test('未初始化时加密抛错', async () => { const cm = new CryptoManager(); expect(cm.enabled).toBe(false); const data = new TextEncoder().encode('x').buffer; await expect(cm.encryptPage(data)).rejects.toThrow(/not initialized/); }); test('不同实例互不影响(独立密钥状态)', async () => { const cm1 = new CryptoManager(); await cm1.init('pwd-a'); const cm2 = new CryptoManager(); await cm2.init('pwd-b'); const original = new TextEncoder().encode('instance isolation').buffer; const { iv, data } = await cm1.encryptPage(original); await expect(cm2.decryptPage(iv, data)).rejects.toThrow(); // 各自解密自己的数据 const dec2orig = new TextEncoder().encode('two').buffer; const enc2 = await cm2.encryptPage(dec2orig); const dec2 = await cm2.decryptPage(enc2.iv, enc2.data); expect(toBytes(dec2)).toEqual(toBytes(dec2orig)); cm1.close(); cm2.close(); }); test('全局兼容层往返一致', async () => { await initCrypto('global-password'); const original = new TextEncoder().encode('global compat layer').buffer; const { iv, data } = await encryptPage(original); const decrypted = await decryptPage(iv, data); expect(toBytes(decrypted)).toEqual(toBytes(original)); closeCrypto(); }); test('大块数据(接近页面大小)往返一致', async () => { const cm = new CryptoManager(); await cm.init('page-size-test'); // 4KB 页面数据 const original = new Uint8Array(4096); for (let i = 0; i < 4096; i++) original[i] = i % 251; const { iv, data } = await cm.encryptPage(original.buffer); const decrypted = await cm.decryptPage(iv, data); expect(toBytes(decrypted)).toEqual(toBytes(original.buffer)); cm.close(); }); });