fuse-core-express 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -480
- package/decryptor.js +106 -0
- package/{index.mjs → index.js} +167 -22
- package/keys/README.md +47 -0
- package/keys/build-version.json +5 -0
- package/keys/recipient-keys-1.0.4.json +7 -0
- package/keys/signer-keys-1.0.4.json +5 -0
- package/package.json +41 -57
- package/secure-package.vxz +0 -0
- package/CHANGELOG.md +0 -128
- package/LICENSE +0 -21
- package/decrypt-loader.mjs +0 -301
- package/private-1.0.2.pem +0 -28
package/decrypt-loader.mjs
DELETED
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FuseCore Decrypt Loader (Bundle Version)
|
|
3
|
-
* 运行时束解密加载器 - 解密并加载文件束到内存
|
|
4
|
-
*/
|
|
5
|
-
import crypto from "crypto";
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import { createGunzip } from "zlib";
|
|
9
|
-
import { fileURLToPath } from "url";
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = path.dirname(__filename);
|
|
13
|
-
|
|
14
|
-
export class FuseCoreDecryptLoader {
|
|
15
|
-
constructor(privateKeyPath) {
|
|
16
|
-
this.privateKey = this.loadPrivateKey(privateKeyPath);
|
|
17
|
-
this.memoryCache = new Map(); // 内存文件缓存
|
|
18
|
-
this.bundleLoaded = false;
|
|
19
|
-
this.bundlePath = null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
loadPrivateKey(privateKeyPath) {
|
|
23
|
-
if (!fs.existsSync(privateKeyPath)) {
|
|
24
|
-
throw new Error(`Private key not found: ${privateKeyPath}`);
|
|
25
|
-
}
|
|
26
|
-
return fs.readFileSync(privateKeyPath, "utf8");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
decryptAESKey(encryptedAESKey) {
|
|
30
|
-
const encryptedBuffer = Buffer.from(encryptedAESKey, "base64");
|
|
31
|
-
const decryptedAESKey = crypto.privateDecrypt({
|
|
32
|
-
key: this.privateKey,
|
|
33
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
34
|
-
oaepHash: "sha256"
|
|
35
|
-
}, encryptedBuffer);
|
|
36
|
-
return decryptedAESKey;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
decryptData(encryptedData, aesKey) {
|
|
40
|
-
const { algorithm, iv, data } = encryptedData;
|
|
41
|
-
const decipher = crypto.createDecipheriv(algorithm, aesKey, Buffer.from(iv, "hex"));
|
|
42
|
-
let decryptedBuffer = Buffer.concat([
|
|
43
|
-
decipher.update(Buffer.from(data, "hex")),
|
|
44
|
-
decipher.final()
|
|
45
|
-
]);
|
|
46
|
-
return decryptedBuffer;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async decompressData(compressedData) {
|
|
50
|
-
return new Promise((resolve, reject) => {
|
|
51
|
-
const gunzip = createGunzip();
|
|
52
|
-
const chunks = [];
|
|
53
|
-
|
|
54
|
-
gunzip.on("data", chunk => chunks.push(chunk));
|
|
55
|
-
gunzip.on("end", () => resolve(Buffer.concat(chunks)));
|
|
56
|
-
gunzip.on("error", reject);
|
|
57
|
-
|
|
58
|
-
gunzip.write(compressedData);
|
|
59
|
-
gunzip.end();
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
verifySignature(data, signature) {
|
|
64
|
-
return true; // 简化实现
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async loadBundle(bundlePath) {
|
|
68
|
-
if (this.bundleLoaded && this.bundlePath === bundlePath) {
|
|
69
|
-
return; // 已加载同一个束
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
console.log(`🔓 Loading encrypted bundle: ${bundlePath}`);
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
const encryptedPackage = JSON.parse(fs.readFileSync(bundlePath, "utf8"));
|
|
76
|
-
|
|
77
|
-
if (encryptedPackage.type !== "bundle") {
|
|
78
|
-
throw new Error("Not a bundle file");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!this.verifySignature(encryptedPackage.encryptedData.data, encryptedPackage.signature)) {
|
|
82
|
-
throw new Error("Invalid signature");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
console.log(`📊 Bundle info: ${encryptedPackage.fileCount} files, compressed from ${encryptedPackage.metadata.originalSize} to ${encryptedPackage.metadata.compressedSize} bytes`);
|
|
86
|
-
|
|
87
|
-
// 解密AES密钥
|
|
88
|
-
const aesKey = this.decryptAESKey(encryptedPackage.encryptedAESKey);
|
|
89
|
-
|
|
90
|
-
// 解密压缩数据
|
|
91
|
-
const decryptedCompressed = this.decryptData(encryptedPackage.encryptedData, aesKey);
|
|
92
|
-
|
|
93
|
-
// 解压缩数据
|
|
94
|
-
const decompressedBuffer = await this.decompressData(decryptedCompressed);
|
|
95
|
-
const bundleData = JSON.parse(decompressedBuffer.toString("utf8"));
|
|
96
|
-
|
|
97
|
-
// 将所有文件加载到内存缓存
|
|
98
|
-
this.memoryCache.clear();
|
|
99
|
-
for (const [filePath, fileInfo] of Object.entries(bundleData)) {
|
|
100
|
-
if (fileInfo.type === "binary") {
|
|
101
|
-
this.memoryCache.set(filePath, {
|
|
102
|
-
type: fileInfo.type,
|
|
103
|
-
content: Buffer.from(fileInfo.content, "base64"),
|
|
104
|
-
size: fileInfo.size
|
|
105
|
-
});
|
|
106
|
-
} else {
|
|
107
|
-
this.memoryCache.set(filePath, {
|
|
108
|
-
type: fileInfo.type,
|
|
109
|
-
content: fileInfo.content,
|
|
110
|
-
size: fileInfo.size
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
console.log(`📁 Loaded to memory: ${filePath} (${fileInfo.size} bytes)`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
this.bundleLoaded = true;
|
|
117
|
-
this.bundlePath = bundlePath;
|
|
118
|
-
console.log(`✅ Bundle loaded successfully: ${this.memoryCache.size} files in memory`);
|
|
119
|
-
|
|
120
|
-
} catch (error) {
|
|
121
|
-
console.error(`❌ Failed to load bundle ${bundlePath}:`, error.message);
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async require(moduleName, moduleType = "auto") {
|
|
127
|
-
// 检测模块系统
|
|
128
|
-
const isESM = typeof require === "undefined";
|
|
129
|
-
|
|
130
|
-
// 如果还没有加载束,尝试加载
|
|
131
|
-
if (!this.bundleLoaded) {
|
|
132
|
-
const bundlePath = path.resolve(__dirname, "bundle.fec");
|
|
133
|
-
await this.loadBundle(bundlePath);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// 构建文件路径
|
|
137
|
-
let targetPaths = [];
|
|
138
|
-
|
|
139
|
-
if (moduleType === "auto") {
|
|
140
|
-
// 自动检测:根据当前环境选择合适的模块
|
|
141
|
-
if (isESM) {
|
|
142
|
-
targetPaths = [
|
|
143
|
-
`esm/${moduleName}.mjs`,
|
|
144
|
-
`esm/${moduleName}.js`,
|
|
145
|
-
`cjs/${moduleName}.js`,
|
|
146
|
-
`${moduleName}.mjs`,
|
|
147
|
-
`${moduleName}.js`
|
|
148
|
-
];
|
|
149
|
-
} else {
|
|
150
|
-
targetPaths = [
|
|
151
|
-
`cjs/${moduleName}.js`,
|
|
152
|
-
`esm/${moduleName}.mjs`,
|
|
153
|
-
`${moduleName}.js`,
|
|
154
|
-
`${moduleName}.mjs`
|
|
155
|
-
];
|
|
156
|
-
}
|
|
157
|
-
} else if (moduleType === "esm") {
|
|
158
|
-
targetPaths = [`esm/${moduleName}.mjs`, `esm/${moduleName}.js`];
|
|
159
|
-
} else if (moduleType === "cjs") {
|
|
160
|
-
targetPaths = [`cjs/${moduleName}.js`];
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// 在内存缓存中查找文件
|
|
164
|
-
let fileInfo = null;
|
|
165
|
-
let foundPath = null;
|
|
166
|
-
|
|
167
|
-
for (const targetPath of targetPaths) {
|
|
168
|
-
if (this.memoryCache.has(targetPath)) {
|
|
169
|
-
fileInfo = this.memoryCache.get(targetPath);
|
|
170
|
-
foundPath = targetPath;
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (!fileInfo) {
|
|
176
|
-
throw new Error(`Module not found in bundle: ${moduleName} (tried: ${targetPaths.join(", ")})`);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (fileInfo.type !== "javascript") {
|
|
180
|
-
throw new Error(`Not a JavaScript module: ${foundPath}`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
console.log(`🔄 Loading module from memory: ${foundPath}`);
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
// 执行代码
|
|
187
|
-
if (isESM) {
|
|
188
|
-
// ESM模式:使用自定义模块解析器
|
|
189
|
-
const moduleCode = fileInfo.content;
|
|
190
|
-
|
|
191
|
-
// 创建临时目录来模拟真实的文件结构
|
|
192
|
-
const tempDir = path.join(__dirname, `.temp_modules_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`);
|
|
193
|
-
try {
|
|
194
|
-
// 创建临时目录
|
|
195
|
-
if (!fs.existsSync(tempDir)) {
|
|
196
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// 将所有相关模块写入临时目录
|
|
200
|
-
const moduleDir = path.dirname(foundPath);
|
|
201
|
-
for (const [filePath, fileInfo] of this.memoryCache) {
|
|
202
|
-
if (filePath.startsWith(moduleDir)) {
|
|
203
|
-
const relativePath = path.relative(moduleDir, filePath);
|
|
204
|
-
const tempFilePath = path.join(tempDir, relativePath);
|
|
205
|
-
const tempFileDir = path.dirname(tempFilePath);
|
|
206
|
-
if (!fs.existsSync(tempFileDir)) {
|
|
207
|
-
fs.mkdirSync(tempFileDir, { recursive: true });
|
|
208
|
-
}
|
|
209
|
-
fs.writeFileSync(tempFilePath, fileInfo.content);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// 写入当前模块
|
|
214
|
-
const tempModulePath = path.join(tempDir, path.basename(foundPath));
|
|
215
|
-
fs.writeFileSync(tempModulePath, moduleCode);
|
|
216
|
-
|
|
217
|
-
// 导入模块
|
|
218
|
-
const moduleResult = await import(`file://${tempModulePath}`);
|
|
219
|
-
return moduleResult;
|
|
220
|
-
} catch (error) {
|
|
221
|
-
console.warn(`Module loading failed for ${foundPath}:`, error.message);
|
|
222
|
-
// 如果加载失败,返回一个基本的模块对象
|
|
223
|
-
return {
|
|
224
|
-
default: {},
|
|
225
|
-
__esModule: true
|
|
226
|
-
};
|
|
227
|
-
} finally {
|
|
228
|
-
// 清理临时目录
|
|
229
|
-
if (fs.existsSync(tempDir)) {
|
|
230
|
-
const cleanupDir = (dir) => {
|
|
231
|
-
const files = fs.readdirSync(dir);
|
|
232
|
-
for (const file of files) {
|
|
233
|
-
const filePath = path.join(dir, file);
|
|
234
|
-
const stat = fs.statSync(filePath);
|
|
235
|
-
if (stat.isDirectory()) {
|
|
236
|
-
cleanupDir(filePath);
|
|
237
|
-
} else {
|
|
238
|
-
fs.unlinkSync(filePath);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
fs.rmdirSync(dir);
|
|
242
|
-
};
|
|
243
|
-
try {
|
|
244
|
-
cleanupDir(tempDir);
|
|
245
|
-
} catch (cleanupError) {
|
|
246
|
-
// 忽略清理错误
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
} else {
|
|
251
|
-
// CommonJS模式:使用require和vm
|
|
252
|
-
const Module = require("module");
|
|
253
|
-
const vm = require("vm");
|
|
254
|
-
const moduleCode = `(function(exports, require, module, __filename, __dirname) { ${fileInfo.content} });`;
|
|
255
|
-
const compiledWrapper = vm.runInThisContext(moduleCode, { filename: foundPath });
|
|
256
|
-
const moduleObj = { exports: {}, require: require, id: foundPath, filename: foundPath, loaded: false };
|
|
257
|
-
compiledWrapper.call(moduleObj.exports, moduleObj.exports, require, moduleObj, foundPath, path.dirname(foundPath));
|
|
258
|
-
moduleObj.loaded = true;
|
|
259
|
-
return moduleObj.exports;
|
|
260
|
-
}
|
|
261
|
-
} catch (error) {
|
|
262
|
-
console.error(`❌ Failed to execute module ${foundPath}:`, error.message);
|
|
263
|
-
throw error;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// 获取内存中的文件列表
|
|
268
|
-
getLoadedFiles() {
|
|
269
|
-
return Array.from(this.memoryCache.keys());
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// 获取内存使用统计
|
|
273
|
-
getMemoryStats() {
|
|
274
|
-
let totalSize = 0;
|
|
275
|
-
const fileTypes = new Map();
|
|
276
|
-
|
|
277
|
-
for (const [filePath, fileInfo] of this.memoryCache) {
|
|
278
|
-
totalSize += fileInfo.size;
|
|
279
|
-
const type = fileInfo.type;
|
|
280
|
-
fileTypes.set(type, (fileTypes.get(type) || 0) + 1);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return {
|
|
284
|
-
totalFiles: this.memoryCache.size,
|
|
285
|
-
totalSize,
|
|
286
|
-
fileTypes: Object.fromEntries(fileTypes)
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// 单例模式 - 确保全局只有一个decryptLoader实例
|
|
292
|
-
let _globalDecryptLoader = null;
|
|
293
|
-
|
|
294
|
-
export function createDecryptLoader(privateKeyPath) {
|
|
295
|
-
if (!_globalDecryptLoader) {
|
|
296
|
-
_globalDecryptLoader = new FuseCoreDecryptLoader(privateKeyPath);
|
|
297
|
-
}
|
|
298
|
-
return _globalDecryptLoader;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export default FuseCoreDecryptLoader;
|
package/private-1.0.2.pem
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
-----BEGIN PRIVATE KEY-----
|
|
2
|
-
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCchsSkY8vrSW1x
|
|
3
|
-
vNAuamsiSr1uvxqigGxnX/ydC3Dupl9i6FiwtyNHGE9zuQmzMOoLFcVw4XzL2EpL
|
|
4
|
-
2wjfGm3Ct4x1s7LCjbTWHjupUoTJrJI6K2WNLl4hqLQvC/Nk5RXQvJ1eVZ0RaTeb
|
|
5
|
-
a84k0QJEUYrTj1vQAk3TGFGj/k6Ch+Ia6U1zG7BlGpAbsTTDe/4ytljKplwMrPoC
|
|
6
|
-
D9DD92BIC/v6QwtyAlGXoKsiBlrVgvj4nMJii2+C/NFrcqZspoy8G7QI7bIvatwn
|
|
7
|
-
n4NNFhJefSKAfVJnxVUvQ2v25FHXCC9joSR3HGoZNIQFSx/eArCxHg4v4R1z+pyW
|
|
8
|
-
m0MLVwTjAgMBAAECggEAGrNknPRHJ1pNuJ6wVpKhtuZP/THNTdYhZ9r4YSO//n3T
|
|
9
|
-
/K/M3UxIUMrlVsTEUlRwQDbVCOX2H2HEfr8c+s3r1lDwPW3LeyOoKvRaUg55B1wQ
|
|
10
|
-
T6rydkxoE07Pec0MlnP7rjFWmO56zisIKNORhTdALz5Hs8IbM9cIxo858gMiCmL2
|
|
11
|
-
SgXoC9zjofJnztr1ZHvZ1gRTghKrXKVHOhVK8UVn1TPqVdtDAvOyIfimTuRykwMA
|
|
12
|
-
s8DrOpWu0LGUVgDXubWWSWnb0lkA81WsuHR2z0qfSkpOBtG3vpNUf5CRYofp5tZp
|
|
13
|
-
Yyab0PVoQRzVqK3Z9SY/wORs3BzQkjRRUkz8zfS9HQKBgQDPGHG/GTevkmDlhexA
|
|
14
|
-
q67112JJnP+1Y8tOYK0iO0T+XhEg3neEE1yB1NqzG4OY8XtkIAhVGoF4b4NANFD4
|
|
15
|
-
UWdbkIs4LB4LpPVYmj534wTEm8gLA9aDj3cOEOuburwnXhoSX4MYdHx/EX+vr5vU
|
|
16
|
-
FaX9+d1jafqPbxrIDEOwtAlRXwKBgQDBfUUqQ7+siRS902J1fzIukR1RiscCRYff
|
|
17
|
-
7G/KeCfdG8G7uwtXDD2ecaKvu24sAYKosZGH0kJ4ielEpoUaQeqLuXdtSFZwY2be
|
|
18
|
-
YN7bfgC2Jd6cp06Tk1IWvDgTlC9707TNpYKQJdC+1Z/EfP2hbNRwguyWYW1Pvp9h
|
|
19
|
-
WA9kM2Km/QKBgCS+hZAOfV7dbevLczuWOpjL+lhtTsF0T2I8rPth4L/xGMDoN/Rr
|
|
20
|
-
KwKuLY+R1iuQzP/a3x+acFZaEsOVhLhKWThZ0RnKWhpezllGJMdItFPeAARUTf9R
|
|
21
|
-
uSH5xpP+8dtaSu3vnGb+ZAh3plwZoGBk5urFJo65AwfoAqxz4J69ktmpAoGAeuy/
|
|
22
|
-
GE7aYx7j0oWNM+CPXQ5MdhWYwVSzMgvgKd2UVeDggAgg+DiKnTLMjKCjKcn73HiT
|
|
23
|
-
YJqwKCxVyouQXFIsVICL4x3l7Jj6LaWVcBTpFs+QUi3oudEKge8qISYv1Jd3cn8I
|
|
24
|
-
J9Qefl7xlb9i0z9059YFwLQ84kDUuN9dR+dtcXECgYAUoO4xQPtrRcWXeE0FKeBa
|
|
25
|
-
hNkJCkEF3SGIpMCFeiiOE7S0oRkPC1UteG17fKUFWMEwuyK/eKAZr4Cup7LIYzy4
|
|
26
|
-
yr2WmtgbaZO8vLaJLB4AUCsE/zU+QSQUXbsT77hcbVQxt5JJUGySYFK0UUaYw7B8
|
|
27
|
-
TjKwFwRfiCAS0Vy/yEb92Q==
|
|
28
|
-
-----END PRIVATE KEY-----
|