electron 程序发布后,如果未对程序做保护,则极容易受到破坏,比如被轻松破解密码,或者被修改程序,所以必须对程序做一些安全防护。虽然没有100%的安全防护,但是提升破解难度,直至破解代价超出了范围,还是能起到作用的。
注:以下列举了一些措施,可以根据情况选择,也可以组合使用
注:以下一些方式,借鉴了网上一些博主的片段,由于浏览太多网页,记不住原作者了,在此请原谅,并感谢!
一,敏感信息加密
比如账号密码,如果存储在本地文件中,密码需要加密存储
二,代码混淆
代码混淆只是加深破解难度,但是防护系数并非很高,源码中的一些常量或某些函数名,可能不会被混淆。对于破解者还是有办法找到关键代码,进行破坏。
代码混淆库有很多,这里以webpack-obfuscator为例:
1,安装
npm install webpack-obfuscator --save-dev
npm install javascript-obfuscator --save-dev
2,配置
const WebpackObfuscator = require('webpack-obfuscator')
webpack.config({
plugins:[
new WebpackObfuscator({
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false, /// 随机的死代码块(增加了混淆代码的大小)
debugProtection: false, // 此选项几乎不可能使用开发者工具的控制台选项卡
debugProtectionInterval: false, // 如果选中,则会在“控制台”选项卡上使用间隔强制调试模式,从而更难使用“开发人员工具”的其他功能。
disableConsoleOutput: true, // 通过用空函数替换它们来禁用console.log,console.info,console.error和console.warn。这使得调试器的使用更加困难。
identifierNamesGenerator: 'hexadecimal', // 标识符的混淆方式 hexadecimal(十六进制) mangled(短标识符)
log: false,
renameGlobals: false, // 是否启用全局变量和函数名称的混淆
rotateStringArray: true, // 通过固定和随机(在代码混淆时生成)的位置移动数组。这使得将删除的字符串的顺序与其原始位置相匹配变得更加困难。如果原始源代码不小,建议使用此选项,因为辅助函数可以引起注意。
selfDefending: true, // 混淆后的代码,不能使用代码美化,同时需要配置 cpmpat:true;
stringArray: true, // 删除字符串文字并将它们放在一个特殊的数组中
stringArrayEncoding: ['base64'],
stringArrayThreshold: 0.75,
unicodeEscapeSequence: false// 允许启用/禁用字符串转换为unicode转义序列。Unicode转义序列大大增加了代码大小,并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
}, []),
]
})
三,asar文件防解压
对于electron程序,一般来说,如果攻击者想做一些破坏,那么他可能会通过修改源码的方式来进行,而electron程序打包的格式一般就是asar文件,这是一种归档文件,可以较容易解压,然后重新打包。基于这种思路,防护方式就是破坏asar归档文件内容,比如修改文件偏移值,或者加入一些不存在的文件来使asar文件本身无法被解压。
1,安装
npm install --save-dev asarmor
注:如果本地安装有冲突,可以全局安装后使用
2,使用
此模块需在electron asar文件生成后使用,可以在electron-builder的afterSign钩子里使用
2.1 创建脚本文件
const asarmor = require('asarmor')
exports.default = async ({ appOutDir, packager }) => {
try {
const asarPath = path.join(packager.getResourcesDir(appOutDir), 'app.asar')
const archive = await asarmor.open(asarPath)
archive.patch()
archive.patch(asarmor.createBloatPatch(1314))
console.log(`applying asarmor patches to ${asarPath}`)
await archive.write(asarPath);
} catch (error) {
console.error(error)
}
}
2.2 注册到钩子
四,字节码
此方式是破解难度最高的方式,即便asar文件被解压,或者通过devtool进入了调试模式,看到的仅仅只是字节码,因此大大提升了破解难度。
1,安装
npm install electron-bytenode-webpack-plugin --save-dev
2,配置
const BytenodeWebpackPlugin = require('electron-bytenode-webpack-plugin')
webpack.config = ({
plugins:[
new BytenodeWebpackPlugin({
compileAsModule: false,
keepSource: true
})
]
})
3,应用
先编译,再打包。通过node .electron-vue/build.js编译后,将原有的入口函数内容替换为bytenode加载字节码:
'use strict';
const fs = require('fs');
const path = require('path');
const v8 = require('v8');
v8.setFlagsFromString('--no-lazy');
const pathName = path.join(__dirname, '../dist/electron/index_bundle.js');
try {
(async function () {
try {
// 将原来的js文件里面的内容替换成下面的内容
fs.writeFileSync(pathName, 'require("bytenode");require("./index_bundle.jsc");', 'utf8');
} catch (e) {
console.error(`run_bytenode_err: ${e}`);
}
}());
} catch (e) {
console.error(`run_bytenode_err: ${e}`);
}
然后再用electron-builder打包。(可以自行编写一行命令的scripts)
注:由于使用了bytenode加载字节码源码,所以打包时,必须把bytenode也一并打包
注:以上方式是由于本人项目框架的一些原因,导致用了这些步骤,现在网上已经有集成好的框架,不用这样自己搞些步骤