From 661aa63f9feaf9c8e5a5c202793c0c9610fea9f7 Mon Sep 17 00:00:00 2001 From: yinsx Date: Mon, 5 Jan 2026 16:26:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/compressor.ts | 25 -------------- src/utils/cryptor.ts | 73 ----------------------------------------- 2 files changed, 98 deletions(-) delete mode 100644 src/utils/compressor.ts delete mode 100644 src/utils/cryptor.ts diff --git a/src/utils/compressor.ts b/src/utils/compressor.ts deleted file mode 100644 index cb513a4..0000000 --- a/src/utils/compressor.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @file compressor.js - * @description 解压缩工具,使用pako完成与GoBetterStudio相同的deflate/raw解码 - */ - -import pako from 'pako'; - -const decoder = new TextDecoder(); - -export const compressor = { - /** 压缩字符串或字节数据 */ - compress(data: Uint8Array | string): Uint8Array { - const source = typeof data === 'string' ? new TextEncoder().encode(data) : data; - return pako.deflateRaw(source); - }, - - /** 解压缩字节数据并返回字符串 */ - decompress(data: ArrayBuffer | Uint8Array): string { - const input = data instanceof Uint8Array ? data : new Uint8Array(data); - const uncompressed = pako.inflateRaw(input); - return decoder.decode(uncompressed); - } -}; - -export default compressor; diff --git a/src/utils/cryptor.ts b/src/utils/cryptor.ts deleted file mode 100644 index d7e7834..0000000 --- a/src/utils/cryptor.ts +++ /dev/null @@ -1,73 +0,0 @@ -import md5 from 'js-md5'; - -const KEY_SIZE = 256 / 32; -const ITERATIONS = 1000; - -type EncryptedAsset = { - value: Uint8Array; - Timestamp: string; -}; - -type Credential = { - token: string; - uid: string; -}; - -type CryptoMaterial = { - obj: Uint8Array; - iv: Uint8Array; - salt: Uint8Array; - key: string; -}; - -function prepareCryptoMaterial(data: EncryptedAsset, info: Credential): CryptoMaterial { - const userIdPrefix = info.uid.slice(0, 16); - const iv = new TextEncoder().encode(userIdPrefix); - const obj = data.value.slice(7); - const saltHex = md5(`${info.token}${data.Timestamp}`); - const saltBytes = new Uint8Array((saltHex.match(/.{1,2}/g) ?? []).map(byte => parseInt(byte, 16))); - return { obj, iv, salt: saltBytes, key: info.token }; -} - -/** 从服务器返回的数据中异步解密出原始GLTF内容 */ -export async function decryptAsync(data: EncryptedAsset, info: Credential): Promise { - const { obj, iv, salt, key } = prepareCryptoMaterial(data, info); - const derivedKey = await generateAesKeyAsync(key, salt, KEY_SIZE, ITERATIONS); - return aesDecryptAsync(obj, derivedKey, iv); -} - -async function generateAesKeyAsync(secret: string, salt: Uint8Array, keySize: number, iterations: number): Promise { - const passwordBuffer = new TextEncoder().encode(secret); - const baseKey = await crypto.subtle.importKey( - 'raw', - passwordBuffer, - { name: 'PBKDF2' }, - false, - ['deriveBits', 'deriveKey'] - ); - return crypto.subtle.deriveKey( - { - name: 'PBKDF2', - salt, - iterations, - hash: 'SHA-1' - }, - baseKey, - { name: 'AES-CBC', length: keySize * 32 }, - false, - ['decrypt'] - ); -} - -async function aesDecryptAsync(data: Uint8Array, key: CryptoKey, iv: Uint8Array): Promise { - try { - return await crypto.subtle.decrypt( - { name: 'AES-CBC', iv }, - key, - data - ); - } catch (error) { - console.error('解密失败:', error); - return null; - } -}