V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
WMutong
V2EX  ›  Electron

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

  •  
  •   WMutong · 2023-02-25 15:17:16 +08:00 · 1654 次点击
    这是一个创建于 673 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

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

    WMutong
        1
    WMutong  
    OP
       2023-04-07 14:50:54 +08:00
    找到了解决方案,在此记录,如果有遇到相同问题的朋友可以借鉴:

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

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

    *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*
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2631 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:14 · PVG 19:14 · LAX 03:14 · JFK 06:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.