electron 主进程、预加载脚本、渲染进程加密方案求教

2023-02-25 15:17:16 +08:00
 WMutong

目前使用 electron 开发了一个客户端项目,项目打包工具使用 electron-builder 。

渲染进程未使用框架,使用原生 JavaScript 和 html 进行开发。

因为 electron 应用安装以后,可以在安装目录下看到项目源代码,所以需要进行混淆和加密。

同时,因为业务需求,electron-builder 打包不能使用 asar 方式。

所以想请教大家有什么好的加密方案,可以把主进程、渲染进程与预加载脚本都进行加密。
目前以了解到的加密方案有以下两个:
1 、electron-vite
2 、bytenode

electron-vite 对项目结构要求比较严格,如果选用这个方案,需要对项目整体做比较大的改动,成本过高。
bytenode 目前了解,是比较低成本和简洁的加密方案,但是目前了解到的都是针对主进程和预加载进行加密,因为是使用 require 引入 jsc 文件,但是对原生的渲染进程的 JavaScript 该如何引用目前还没有看到。

所以想求教大神指点一二,感激不尽

1601 次点击
所在节点    Electron
2 条回复
WMutong
2023-04-07 14:50:54 +08:00
找到了解决方案,在此记录,如果有遇到相同问题的朋友可以借鉴:

*packager.json*
...
"build": {
...

...
}
...
*/packager.json*
WMutong
2023-04-07 14:52:27 +08:00
找到了解决方案,在此记录,如果有遇到相同问题的朋友可以借鉴:

*packager.json*
...
"build": {
...
"afterSign": "./build_resource/afterSign.js",
...
}
...
*/packager.json*

*afterSign.js*
const fs = require('fs')
const path = require('path');
const asar = require('asar');
const JavaScriptObfuscator = require('javascript-obfuscator'); //使用 javascript-obfuscator 代码混淆

//获取指定文件夹下排除指定类型的文件
function getFiles(dirpath, exclude){
function getFiles_(dir, arr){
const stat = fs.statSync(dir);
if(stat.isDirectory()){
const dirs = fs.readdirSync(dir);
dirs.forEach(value => {
let extname = path.extname(value);

if(exclude.includes(extname)) arr.push(path.join(dir,value));
if(extname == "" && exclude.includes(value)) getFiles_(path.join(dir,value), arr);
})
}
else if(stat.isFile()){
//文件
if(exclude.includes(dir)) arr.push(dir);
}
};
let arrs = [];
getFiles_(dirpath, arrs);
return arrs;
}

exports.default = async ({appOutDir, packager}) => {
try{
const asarPath = path.join(packager.getResourcesDir(appOutDir), 'app.asar');
let appPath = path.join(packager.getResourcesDir(appOutDir), 'app');

if(fs.existsSync(asarPath)){
//如果存在 asar 压缩包
asar.extractAll(asarPath, appPath);
}

// 替换文件内容
let fileArrs = getFiles(appPath, ["app", "assets", "js", ".js"]);

console.log("等待加密文件:", fileArrs)
for(let i = 0;i < fileArrs.length;i++){
let con = fs.readFileSync(fileArrs[i],'utf8');

console.log("当前加密文件:", fileArrs[i])
let obfuscationResult = JavaScriptObfuscator.obfuscate(con, {
compact: true,
debugProtection: true,
disableConsoleOutput: true,
numbersToExpressions: true,
simplify: true,
stringArrayShuffle: true,
splitStrings: true,
stringArrayThreshold: 1
});
fs.writeFileSync(fileArrs[i], obfuscationResult.getObfuscatedCode());
}

// console.log('asar content replacement completed.');
// if(fs.existsSync(asarPath)){
// fs.unlinkSync(asarPath);
// console.log('delete the original asar.');
// }
// await asar.createPackage(appPath, asarPath);
// fs.rmdirSync(appPath,{recursive:true});
// console.log('create new asar.');
}catch(err){
console.error(err);
}
}

*/afterSign.js*

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/919126

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX