混淆加密
JavaScript代码混淆,主要是为了防止代码被反编译,从而达到保护代码的目的。目前Typescript模式下,默认采用了webpack-obfuscator插件,如果需要关闭,请移除[new WebpackObfuscator]相关代码。
webpack-obfuscator
webpack-obfuscator 插件的目标是 代码混淆,它不仅压缩代码,还对代码的结构进行修改,使得代码变得更难以理解和逆向。这种混淆通常包括更复杂的技术,比如控制流扁平化、字符串加密、死代码注入等。
主要解决的问题:
- 代码混淆:通过改变代码的结构、变量名、函数名等,使代码更加难以阅读和理解。例如,变量名被替换成无意义的短字符(如 a, b, c 等),控制流被打乱,字符串被加密等。
- 字符串加密与提取:将代码中的字符串提取到数组中,并通过索引引用,这样可以避免直接查看源代码时轻松找到敏感信息。 控制流扁平化:通过改变代码的控制流,使代码变得更加复杂,并不直接按常规顺序执行。
- 死代码注入:向代码中插入一些永远不会执行的“死代码”,以增加分析和理解的难度。
适用场景:
- 代码保护:如果你希望保护代码免受逆向工程、剖析或窃取,特别是涉及到敏感业务逻辑或算法时,使用代码混淆是一种有效手段。
- 防止盗用:通过混淆技术,增加其他人复制或修改你的代码的难度。
- 高级混淆:如果你需要更复杂的混淆(如控制流扁平化、字符串加密等),webpack-obfuscator 提供了比 TerserPlugin 更强大的功能。
请使用Typescript模式,并配置项目根目录下面的webpack.config.js文件
plugins: [
new WebpackObfuscator({
compact: false, //代码压缩 不建议开启,否则代码错误很难排查
rotateStringArray: true, // 启用字符串数组混淆
controlFlowFlattening: true, // 控制流扁平化
deadCodeInjection: true, // 注入死代码
stringArray: true, // 启用字符串数组化 不能启用,否则rhino无法处理
stringArrayThreshold: 0.75, // 配置字符串数组化的阈值
disableConsoleOutput: false, // 禁用 console 输出
sourceMap: true, // 启用生成 sourcemap
}), // 指定要混淆的文件
]
代码混淆示例
const arr = [1, 2, 3];
// 自动抛出 RangeError,因为数组索引越界 192.168.1.3:8088
const value = arr[-1]; // TypeScript 会提示 `undefined`,但是在运行时会引发错误
function test() {
let obj: any = {};
// 访问 null 时,会触发 TypeError
console.log(obj.someMethod()); // TypeError: Cannot read property 'someMethod' of null
}
console.log(arr);
test();
加密后【未启用压缩】,如下:
function a1_0x1ec2(_0x5231f6, _0x2af77f) {
var _0x5a5af3 = a1_0x5a5a();
return a1_0x1ec2 = function (_0x1ec206, _0x34fa78) {
_0x1ec206 = _0x1ec206 - 0x179;
var _0x37087a = _0x5a5af3[_0x1ec206];
return _0x37087a;
}, a1_0x1ec2(_0x5231f6, _0x2af77f);
}
function a1_0x5a5a() {
var _0x1d7dd5 = [
'518VpvfkM',
'23080UeErzH',
'1602955bwJgKL',
'342gUFXyW',
'12dsfZzM',
'1806525wDAlMV',
'SbsGP',
'log',
'7117510QcznoC',
'2088666fYozPk',
'5582424BzocDR',
'1339PzFigh',
'someMethod'
];
a1_0x5a5a = function () {
return _0x1d7dd5;
};
return a1_0x5a5a();
}
(function (_0x505f31, _0x8f1e42) {
var _0x4cc1b2 = a1_0x1ec2, _0x21a0db = _0x505f31();
while (!![]) {
try {
var _0x204909 = parseInt(_0x4cc1b2(0x184)) / 0x1 * (parseInt(_0x4cc1b2(0x179)) / 0x2) + -parseInt(_0x4cc1b2(0x17c)) / 0x3 * (-parseInt(_0x4cc1b2(0x17a)) / 0x4) + parseInt(_0x4cc1b2(0x17b)) / 0x5 * (-parseInt(_0x4cc1b2(0x17d)) / 0x6) + -parseInt(_0x4cc1b2(0x17e)) / 0x7 + -parseInt(_0x4cc1b2(0x183)) / 0x8 + parseInt(_0x4cc1b2(0x182)) / 0x9 + parseInt(_0x4cc1b2(0x181)) / 0xa;
if (_0x204909 === _0x8f1e42)
break;
else
_0x21a0db['push'](_0x21a0db['shift']());
} catch (_0x17c6b7) {
_0x21a0db['push'](_0x21a0db['shift']());
}
}
}(a1_0x5a5a, 0x55c72), ((() => {
'use strict';
var _0x349cf0 = a1_0x1ec2, _0x4b0556 = {
'SbsGP': function (_0x2127e2) {
return _0x2127e2();
}
};
var _0x461321 = [
0x1,
0x2,
0x3
], _0x7f0d4c = _0x461321[-0x1];
function _0x27bef1() {
var _0xd3ee64 = a1_0x1ec2, _0x353c31 = {};
console[_0xd3ee64(0x180)](_0x353c31[_0xd3ee64(0x185)]());
}
console['log'](_0x461321), _0x4b0556[_0x349cf0(0x17f)](_0x27bef1);
})()));
//# sourceMappingURL=task/test.js.map
//# sourceMappingURL=test.js.map