feat: v0.2.4 惰性扫描 + 写背压 + 内存预算 + ANALYZE + 加密 + Savepoint + 在线备份
CI / test (18.x) (push) Failing after 4m59s
CI / test (20.x) (push) Failing after 5m0s
CI / test (22.x) (push) Failing after 4m59s
CI / test (24.x) (push) Failing after 4m58s

This commit is contained in:
thzxx
2026-07-27 21:55:57 +08:00
parent 82e6baaae9
commit f248e5fb05
4 changed files with 193 additions and 9 deletions
+54
View File
@@ -0,0 +1,54 @@
/**
* AriaEngine Crypto — 页面级 AES-GCM 加密
* @module engine/aria/crypto
*
* 使用 Web Crypto API (SubtleCrypto) 进行 AES-256-GCM 加密。
* 浏览器原生支持,无需额外依赖。
*/
const ALGO = 'AES-GCM';
const KEY_LENGTH = 256;
const IV_LENGTH = 12; // GCM 推荐 96-bit nonce
let cryptoKey: CryptoKey | null = null;
let enabled = false;
/**
* 初始化加密密钥。传入原始密码字符串,通过 PBKDF2 派生 AES 密钥。
*/
export async function initCrypto(password: string, salt?: Uint8Array): Promise<Uint8Array> {
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
'raw', enc.encode(password), 'PBKDF2', false, ['deriveKey'],
);
const actualSalt = salt || crypto.getRandomValues(new Uint8Array(16));
cryptoKey = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt: actualSalt, iterations: 100000, hash: 'SHA-256' },
keyMaterial, { name: ALGO, length: KEY_LENGTH }, false, ['encrypt', 'decrypt'],
);
enabled = true;
return actualSalt;
}
/** 是否已启用加密 */
export function isCryptoEnabled(): boolean { return enabled; }
/** 加密 ArrayBuffer,返回 { iv, ciphertext } */
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));
const ciphertext = await crypto.subtle.encrypt({ name: ALGO, iv }, cryptoKey, data);
return { iv, data: ciphertext };
}
/** 解密 ArrayBuffer */
export async function decryptPage(iv: Uint8Array, data: ArrayBuffer): Promise<ArrayBuffer> {
if (!cryptoKey) throw new Error('Crypto not initialized');
return crypto.subtle.decrypt({ name: ALGO, iv }, cryptoKey, data);
}
/** 关闭加密,清除密钥 */
export function closeCrypto(): void {
cryptoKey = null;
enabled = false;
}