背景
在开发 Web 应用系统时,为了防止攻击者抓取请求后通过重放请求或伪造请求包攻击服务端,通常会在前端 JS 中加入自定义的数据处理逻辑,例如请求字段加密、签名校验等机制。因此,保护前端数据处理逻辑、提升逆向分析成本就变得非常关键。
本文基于 Webpack 的 webpack-obfuscator 插件,演示对前端代码进行加密混淆的效果,用于提升核心逻辑的安全性与对抗静态/动态分析的门槛。(更多工程化相关内容可参考:Webpack/前端工程化)
一、插件介绍
webpack-obfuscator 是 Webpack 生态中的 JavaScript 代码混淆插件,底层基于 javascript-obfuscator 库,通过字符串加密、标识符重命名、控制流扁平化等手段增强前端代码的抗分析能力。
常见混淆能力包括:
- 字符串加密:将代码中的字符串转换为加密形式,增加静态分析难度
- 标识符重命名:变量名、函数名被替换为无意义字符,降低可读性
- 控制流扁平化:打乱代码执行顺序,使逻辑追踪复杂化
- 文件排除支持:通过
excludes 选项跳过第三方库混淆,避免不必要的性能损耗
二、插件安装与配置
环境要求
- Node.js 12.0+
- webpack 5.1.0+
2.1 安装插件及依赖
npm install --save-dev javascript-obfuscator webpack-obfuscator
2.2 Webpack 配置示例
在项目的 webpack.config.js 中添加插件实例,核心代码如下:
const WebpackObfuscator = require('webpack-obfuscator');
module.exports = {
plugins: [
new WebpackObfuscator({
compact: true,
debugProtection: true,
disableConsoleOutput: true,
rotateUnicodeArray: true,
identifierNamesGenerator: 'hexadecimal',
renameGlobals: true,
rotateStringArray: true,
selfDefending: true,
stringArray: true,
stringArrayEncoding: ['base64'],
stringArrayThreshold: 0.75,
transformObjectKeys: true,
unicodeEscapeSequence: false,
})
]
};
2.3 配置参数说明
compact (boolean): 是否压缩输出的代码,默认为 true。
controlFlowFlattening (boolean): 是否启用控制流扁平化,默认为 false。
controlFlowFlatteningThreshold (number): 控制流扁平化的阈值,默认为 0.75。
deadCodeInjection (boolean): 是否注入死代码,默认为 false。
deadCodeInjectionThreshold (number): 死代码注入的阈值,默认为 0.4。
debugProtection (boolean): 是否启用调试保护,默认为 false。
debugProtectionInterval (boolean): 是否启用调试保护间隔,默认为 false。
domainLock (Array<string>): 锁定指定的域名,默认为空数组。
identifierNamesGenerator (string): 生成标识符名称的方式,默认为 'mangled'。
log (boolean): 是否记录混淆过程,默认为 false。
numbersToExpressions (boolean): 是否将数字转换为表达式,默认为 false。
renameGlobals (boolean): 是否重命名全局变量,默认为 false。
rotateStringArray (boolean): 是否启用字符串数组旋转,默认为 false。
selfDefending (boolean): 是否启用自我防御,默认为 false。
simplify (boolean): 是否简化输出代码,默认为 true。
sourceMap (boolean | string): 是否生成源映射,默认为 false。
sourceMapMode (string): 源映射模式,默认为 'separate'。
splitStrings (boolean): 是否将字符串分割成多个较小的字符串,默认为 false。
stringArrayEncoding (Array<string>): 字符串数组编码方式,默认为空数组。
stringArrayEncodingThreshold (number): 字符串数组编码的阈值,默认为 0.75。
stringArrayThreshold (number): 字符串数组阈值,默认为 0.75。
stringArrayWrappersCount (number): 字符串数组包装器的数量,默认为 2。
stringArrayWrappersChainedCalls (number): 字符串数组包装器链式调用的数量,默认为 2。
stringArrayWrappersParametersMaxCount (number): 字符串数组包装器参数的最大数量,默认为 2。
stringArrayWrappersParametersMinCount (number): 字符串数组包装器参数的最小数量,默认为 1。
stringArrayWrappersType (string): 字符串数组包装器的类型,默认为 ‘variable’。
stringArrayWrappersVarNames (Array<string>): 字符串数组包装器变量名称,默认为空数组。
stringArrayIndexShift (boolean): 是否对字符串数组索引进行偏移,默认为 false。
shuffleStringArray (boolean): 是否打乱字符串数组,默认为 false。
transformObjectKeys (boolean): 是否转换对象键,默认为 false。
transformObjectKeysBlackList (Array<string>): 不转换的对象键黑名单,默认为空数组。
transformObjectKeysRecursive (boolean): 是否递归转换对象键,默认为 false。
transformObjectKeysWhitelist (Array<string>): 转换的对象键白名单,默认为空数组。
unicodeEscapeSequence (boolean): 是否使用 Unicode 逃逸序列,默认为 false。
useStrictSemicolons (boolean): 是否使用严格的分号,默认为 false。
wrapCode (boolean): 是否包裹代码,默认为 false。
wrapComments (boolean): 是否包裹注释,默认为 false。
exclude (Array<string> | RegExp): 排除不需要混淆的模块或文件。
三、插件运行效果展示
下面以一个前端编写的 JS 文件为例:对用户输入数据进行 RSA + AES 加密后再提交。
说明:该示例属于典型“前端加密/签名逻辑保护”的需求,通常在对抗爬虫、接口重放、参数篡改等场景中使用,可归入更广义的网络安全工程实践。
3.1 原始 JS 代码(未打包)
var CryptoJS = require("crypto-js"); //aes 算法
import { JSEncrypt } from "jsencrypt"; //rsa 算法
const $ = require('jquery');
//初始化公钥
var publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCamrisG0f6LqOGxBY9QFRH08z0LhojLEP7bzSwU7NsTO07zDOukCZS+9C2ZG72purTum7jwnvLh7F9CPj6fwSMvkpBmcszeZGJgR/xYS9/ZnsZAxJKkxd4V6HNMu/v5qBKGAZShJ8uMr6gJfzEArhqS6MqS7pEqB0Z1OeIu/W37wIDAQAB";
var privateKey = "MIICWwIBAAKBgQCamrisG0f6LqOGxBY9QFRH08z0LhojLEP7bzSwU7NsTO07zDOukCZS+9C2ZG72purTum7jwnvLh7F9CPj6fwSMvkpBmcszeZGJgR/xYS9/ZnsZAxJKkxd4V6HNMu/v5qBKGAZShJ8uMr6gJfzEArhqS6MqS7pEqB0Z1OeIu/W37wIDAQABAoGAVPtnN3NnhSXNzW5Lqy+JJFJP/oi45UyXscXW+HWJ0qYWYSBF6FZkOokgmKFsPThTLD72ZUuqMJ5N+aTM9ySKotfTQqC7itAaD10DVG5eO7GX+59seFwnxESOfeK/Rp10ZddMwl16doT8LNfkNCtpoX9JU2/C4R7tf1J7JrYHboECQQDLRcJGDstYVRUJl32vQ+BGenjX8B3wrCgPJGD3D0hDSI/I8N53mC9L6hl0wb3+BNEH+IE7WUk8+MBLBJxuN1G3AkEAwrUsPUr2vjlU+mKFpdlbllcPFse52Q1V/pBkxxGmlMR11YSVzfH9QcXJ6wpjFg6Gfzn2X6Qd6gsQQgJaamjriQJATV+mTWiAOoVYVqhVbQtXKTyhFwENRHkjXnAogKJOjV3nbUNSSw+goTLgsbK1kSVgM7qB5odb+1tsRqHgsYtZDQJAPy+0T5/IOys33JmkbZIAGuXdy7K9KScexSHu0ntz58tpwgTo6JCjc3jQcipIxZupIhiZT6he3NkCSamh1e5+oQJAHs5DzgFnidrFC7qB+sH6/e1AvjBmF+fQ8aQubgZX05mt8K8dZr6nYL+w0H5jF7wpiRWoTwC9jGvblUQrcaFvpA==";
function generateRandomString() {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < 16; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
//rsa加密aes密钥
function rsaEncrypt(aesKey_clear) {
var encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey);
var encryptedAesKey = encryptor.encrypt(aesKey_clear);
return encryptedAesKey;
}
//rsa解密aes密钥
function rsaDecrypt(aesKey_enc) {
var encryptor = new JSEncrypt();
encryptor.setPrivateKey(privateKey);
var decryptedAesKey = encryptor.decrypt(aesKey_enc);
return decryptedAesKey;
}
function data_encrypt(aesKey,plaintext){
var key = CryptoJS.enc.Utf8.parse(aesKey);
var encryptedAesKey = rsaEncrypt(aesKey);
var aesEncryptedData = CryptoJS.AES.encrypt(plaintext, key,{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return {
"key": encryptedAesKey,
"data": aesEncryptedData.toString()
}
}
function data_decrypt(aesKey,enc_data){
var key = CryptoJS.enc.Utf8.parse(aesKey);
// var encryptedAesKey = rsaEncrypt(aesKey);
var aesDecryptedData = CryptoJS.AES.decrypt(enc_data, key,{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return aesDecryptedData.toString(CryptoJS.enc.Utf8)
}
$('#btn').on('click',function(){
var username = document.getElementById('username').value
var aesKey = generateRandomString();
var data = data_encrypt(aesKey,username)
console.log("request data:",data)
$.ajax({
url: "/query3.php",
data: JSON.stringify(data),
method: 'post',
contentType: 'application/json'
}).done(function(res_data) {
console.log("response data:",res_data)
const jsonString = JSON.stringify(res_data);
var enc_data=JSON.parse(jsonString).data;
console.log("response.data:",enc_data);
var dec_data = data_decrypt(aesKey,enc_data);
document.getElementById('result').value=dec_data;
});
})
原始代码文件大小:4KB。格式清晰,可读性较好,分析与定位逻辑相对容易。
3.2 仅使用 Webpack 打包(未启用混淆插件)
使用 Webpack 打包但不启用 webpack-obfuscator 时,编译后文件大小约 2KB。代码被压缩、变量名有替换,但整体仍相对容易进行静态/动态分析。编译结果示例:
(self.webpackChunkwebpack_demo=self.webpackChunkwebpack_demo||[]).push([[92],{767:(e,t,n)=>{"use strict";var a=n(572),o=n(396);const r=n(692);r("#btn").on("click",(function(){var e=document.getElementById("username").value,t=function(){let e="";for(let t=0;t<16;t++)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(62*Math.random()));return e}(),n=function(e,t){var n,r,c=o.enc.Utf8.parse(e);return{key:(n=e,(r=new a.v).setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCamrisG0f6LqOGxBY9QFRH08z0LhojLEP7bzSwU7NsTO07zDOukCZS+9C2ZG72purTum7jwnvLh7F9CPj6fwSMvkpBmcszeZGJgR/xYS9/ZnsZAxJKkxd4V6HNMu/v5qBKGAZShJ8uMr6gJfzEArhqS6MqS7pEqB0Z1OeIu/W37wIDAQAB"),r.encrypt(n)),data:o.AES.encrypt(t,c,{mode:o.mode.ECB,padding:o.pad.Pkcs7}).toString()}}(t,e);console.log("request data:",n),r.ajax({url:"/query3.php",data:JSON.stringify(n),method:"post",contentType:"application/json"}).done((function(e){console.log("response data:",e);const n=JSON.stringify(e);var a=JSON.parse(n).data;console.log("response.data:",a);var r=function(e,t){var n=o.enc.Utf8.parse(e);return o.AES.decrypt(t,n,{mode:o.mode.ECB,padding:o.pad.Pkcs7}).toString(o.enc.Utf8)}(t,a);document.getElementById("result").value=r}))}))},477:()=>{}},e=>{e.O(0,[96],(()=>(767,e(e.s=767)))),e.O()}]);
本地浏览器打开效果如下:

3.3 使用 Webpack + webpack-obfuscator 混淆
启用 webpack-obfuscator 后,编译打包代码示例如下(节选保持原样):
var a4_0x4897c3=a4_0x2e76;(function(_0x1ee5a8,_0x1dc0b8){var _0x1d4b36=a4_0x2e76,_0x24ecc9=_0x1ee5a8();while(!![]){try{var _0x205f7a=parseInt(_0x1d4b36(0x18f))/0x1+-parseInt(_0x1d4b36(0x17d))/0x2+-parseInt(_0x1d4b36(0x195))/0x3*(-parseInt(_0x1d4b36(0x176))/0x4)+parseInt(_0x1d4b36(0x193))/0x5+-parseInt(_0x1d4b36(0x1a0))/0x6+-parseInt(_0x1d4b36(0x1b5))/0x7+parseInt(_0x1d4b36(0x1b0))/0x8*(parseInt(_0x1d4b36(0x186))/0x9);if(_0x205f7a===_0x1dc0b8)break;else _0x24ecc9['push'](_0x24ecc9['shift']());}catch(_0x453e94){_0x24ecc9['push'](_0x24ecc9['shift']());}}}(a4_0x43cf,0xeb1b4));var a4_0x181795=(function(){var _0x283db7=!![];return function(_0x5f10ff,_0x50a850){var _0x200448=_0x283db7?function(){var _0x542092=a4_0x2e76;if(_0x50a850){var _0x2833fa=_0x50a850[_0x542092(0x1af)](_0x5f10ff,arguments);return _0x50a850=null,_0x2833fa;}}:function(){};return _0x283db7=![],_0x200448;};}()),a4_0x2e5fed=a4_0x181795(this,function(){var _0x167d93=a4_0x2e76;return a4_0x2e5fed[_0x167d93(0x178)]()[_0x167d93(0x198)](_0x167d93(0x18c))[_0x167d93(0x178)]()[_0x167d93(0x196)](a4_0x2e5fed)[_0x167d93(0x198)](_0x167d93(0x18c));});function a4_0x2e76(_0x50638f,_0x1533af){var _0x19dbb3=a4_0x43cf();return a4_0x2e76=function(_0x5bfef5,_0x183a19){_0x5bfef5=_0x5bfef5-0x174;var _0x37b115=_0x19dbb3[_0x5bfef5];if(a4_0x2e76['pcUXqI']===undefined){var _0x14b392=function(_0x4a81c1){var _0x11ca9a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x43cfe6='',_0x2e7649='',_0x5137e5=_0x43cfe6+_0x14b392;for(var _0x11475c=0x0,_0x22e379,_0x51d79e,_0x20da50=0x0;_0x51d79e=_0x4a81c1['charAt'](_0x20da50++);~_0x51d79e&&(_0x22e379=_0x11475c%0x4?_0x22e379*0x40+_0x51d79e:_0x51d79e,_0x11475c++%0x4)?_0x43cfe6+=_0x5137e5['charCodeAt'](_0x20da50+0xa)-0xa!==0x0?String['fromCharCode'](0xff&_0x22e379>>(-0x2*_0x11475c&0x6)):_0x11475c:0x0){_0x51d79e=_0x11ca9a['indexOf'](_0x51d79e);}for(var _0x10a5d5=0x0,_0x181795=_0x43cfe6['length'];_0x10a5d5<_0x181795;_0x10a5d5++){_0x2e7649+='%'+('00'+_0x43cfe6['charCodeAt'](_0x10a5d5)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2e7649);};a4_0x2e76['HxrvlO']=_0x14b392,_0x50638f=arguments,a4_0x2e76['pcUXqI']=!![];}var _0x15289a=_0x19dbb3[0x0],_0x7331fd=_0x5bfef5+_0x15289a,_0x377853=_0x50638f[_0x7331fd];if(!_0x377853){var _0x2e5fed=function(_0x410bdc){this['KDGxmA']=_0x410bdc,this['HUQVhn']=[0x1,0x0,0x0],this['xWXiBc']=function(){return'newState';},this['VPmcOz']='\\w+\\s*\\(\\)\\s*{\\w+\\s*',this['Zbumjk']='[\\'|\\"].+[\\'|\\"];?\\s*}';};_0x2e5fed['prototype']['vqWQhU']=function(){var _0x374a52=new RegExp(this['VPmcOz']+this['Zbumjk']),_0x25851e=_0x374a52['test'](this['xWXiBc']['toString']())?--this['HUQVhn'][0x1]:--this['HUQVhn'][0x0];return this['WoikTR'](_0x25851e);},_0x2e5fed['prototype']['WoikTR']=function(_0x3aae9f){if(!Boolean(~_0x3aae9f))return _0x3aae9f;return this['ZPtquf'](this['KDGxmA']);},_0x2e5fed['prototype']['ZPtquf']=function(_0x283db7){for(var _0x5f10ff=0x0,_0x50a850=this['HUQVhn']['length'];_0x5f10ff<_0x50a850;_0x5f10ff++){this['HUQVhn']['push'](Math['round'](Math['random']())),_0x50a850=this['HUQVhn']['length'];}return _0x283db7(this['HUQVhn'][0x0]);},new _0x2e5fed(a4_0x2e76)['vqWQhU'](),_0x37b115=a4_0x2e76['HxrvlO'](_0x37b115),_0x50638f[_0x7331fd]=_0x37b115;}else _0x37b115=_0x377853;return _0x37b115;},a4_0x2e76(_0x50638f,_0x1533af);}a4_0x2e5fed();var a4_0x410bdc=(function(){var _0x245915=!![];return function(_0x41ca88,_0x52f484){var _0x5e96d7=_0x245915?function(){if(_0x52f484){var _0x1a8dd0=_0x52f484['apply'](_0x41ca88,arguments);return _0x52f484=null,_0x1a8dd0;}}:function(){};return _0x245915=![],_0x5e96d7;};}());(function(){a4_0x410bdc(this,function(){var _0x9c1d36=a4_0x2e76,_0x6bd2c3=new RegExp(_0x9c1d36(0x17b)),_0x1ce53b=new RegExp(_0x9c1d36(0x180),'i'),_0x226426=a4_0x3aae9f('init');!_0x6bd2c3[_0x9c1d36(0x18d)](_0x226426+_0x9c1d36(0x1a9))||!_0x1ce53b[_0x9c1d36(0x18d)](_0x226426+_0x9c1d36(0x188))?_0x226426('0'):a4_0x3aae9f();})();}());function a4_0x43cf(){var _0x1e1f02=['D2fYBG','zMXVB3i','zNvUy3rPB24GkLWOicPCkq','ywPHEa','mtuWmZK0nLrZBg16CG','CgfYC2u','zw5JCNLWDa','xcTCkYaQkd86w2eTEKeTwL8KxvSWltLHlxPblvPFjf0Qkq','zxjYB3i','ywn0Aw9U','qujdrevgr0HjsKTmtu5puffsu1rvvLDywvPHyMnKzwzNAgLQA2XTBM9WCxjZDhv2D3H5EJaXmJm0nty3odK','Bw9Kzq','z2DLCG','odGYsKPeqMLA','C2v0uhvIBgLJs2v5','Aw5WDxq','y2XPy2S','D2HPBguGkhrYDwuPihT9','zg9Uzq','kcGOlISPkYKRksSK','DgvZDa','BgvUz3rO','mte4mZK2owTrANHltW','l3f1zxj5mY5WAha','y29UC29Szq','x19WCM90B19F','mZiZntG0mgTQCLrjta','CMvXDwvZDcbKyxrHoG','mtq0ntC5quLIqNH0','y29UC3rYDwn0B3i','i2j0BG','C2vHCMnO','CMvZCg9UC2uGzgf0ytO','D2vICgfJA0nODw5RD2vICgfJA19Kzw1V','zw5J','E30Uy29UC3rYDwn0B3iOiNjLDhvYBIb0AgLZiIKOicK','C3rHDgvpyMPLy3q','yMLUza','CMv0DxjUicHMDw5JDgLVBIGPia','odq1nJqXofHWqNP5sa','DMfSDwu','DxnLCM5HBwu','ChvZAa','DhjHy2u','ChjVDg90ExbL','y2HHCKf0','Cg9ZDa','vxrMoa','y2HHAw4','quvt','Bg9N','CMvZDwX0','runc','zgf0yq','yxbWBhK','mtKYoty4vhLIBhf3','CgfK','y291BNrLCG','z2v0rwXLBwvUDej5swq','C3rYAw5NAwz5','nZGZmtCXmLjuCxHZDW','ugTJCZC','zgvIDq','zxHJzxb0Aw9U','neDgsfnNuG','yxbWBgLJyxrPB24VANnVBG','Dg9tDhjPBMC'];a4_0x43cf=function(){return _0x1e1f02;};return a4_0x43cf();}var a4_0x374a52=(function(){var _0x34d9f0=!![];return function(_0x169958,_0x405c55){var _0x251253=_0x34d9f0?function(){var _0x365f03=a4_0x2e76;if(_0x405c55){var _0x59cdde=_0x405c55[_0x365f03(0x1af)](_0x169958,arguments);return _0x405c55=null,_0x59cdde;}}:function(){};return _0x34d9f0=![],_0x251253;};}()),a4_0x25851e=a4_0x374a52(this,function(){var _0x29c60a=a4_0x2e76,_0x4195b8=function(){var _0x339702=a4_0x2e76,_0x37c7c2;try{_0x37c7c2=Function(_0x339702(0x19f)+_0x339702(0x19c)+');')();}catch(_0x18f3b3){_0x37c7c2=window;}return _0x37c7c2;},_0x33514f=_0x4195b8(),_0x259f50=_0x33514f[_0x29c60a(0x191)]=_0x33514f[_0x29c60a(0x191)]||{},_0x10f67d=[_0x29c60a(0x1ab),_0x29c60a(0x179),'info',_0x29c60a(0x181),_0x29c60a(0x175),'table',_0x29c60a(0x1a4)];for(var _0x567a16=0x0;_0x567a16<_0x10f67d[_0x29c60a(0x18e)];_0x567a16++){var _0x233159=a4_0x374a52[_0x29c60a(0x196)][_0x29c60a(0x1a5)][_0x29c60a(0x19e)](a4_0x374a52),_0x4ddde7=_0x10f67d[_0x567a16],_0x232f5b=_0x259f50[_0x4ddde7]||_0x233159;_0x233159[_0x29c60a(0x192)]=a4_0x374a52['bind'](a4_0x374a52),_0x233159[_0x29c60a(0x178)]=_0x232f5b['toString'][_0x29c60a(0x19e)](_0x232f5b),_0x259f50[_0x4ddde7]=_0x233159;}});a4_0x25851e(),(self[a4_0x4897c3(0x19a)]=self[a4_0x4897c3(0x19a)]||[])[a4_0x4897c3(0x1a3)]([[0x5c],{0x2ff:(_0xe1ee0d,_0x5900fe,_0x27e0b6)=>{'use strict';var _0x8b9f4d=a4_0x4897c3;var _0x43cc84=_0x27e0b6(0x23c),_0x324cbf=_0x27e0b6(0x18c);const _0x2ef8cb=_0x27e0b6(0x2b4);_0x2ef8cb(_0x8b9f4d(0x197))['on'](_0x8b9f4d(0x189),function(){var _0x4e8f84=_0x8b9f4d,_0x1bd535=document['getElementById'](_0x4e8f84(0x1a2))[_0x4e8f84(0x1a1)],_0xaa9046=(function(){var _0xe33565=_0x4e8f84;let _0x1e07c0='';for(let _0x3d552f=0x0;_0x3d552f<0x10;_0x3d552f++)_0x1e07c0+=_0xe33565(0x183)[_0xe33565(0x1a6)](Math[_0xe33565(0x17a)](0x3e*Math['random']()));return _0x1e07c0;}()),_0x26eae3=function(_0x11df12,_0x30e65d){var _0x33e766=_0x4e8f84,_0x506da2,_0x3c0c4e,_0x1b3417=_0x324cbf[_0x33e766(0x19b)]['Utf8']['parse'](_0x11df12);return{'key':(_0x506da2=_0x11df12,(_0x3c0c4e=new _0x43cc84['v']())[_0x33e766(0x187)]('MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCamrisG0f6LqOGxBY9QFRH08z0LhojLEP7bzSwU7NsTO07zDOukCZS+9C2ZG72purTum7jwnvLh7F9CPj6fwSMvkpBmcszeZGJgR/xYS9/ZnsZAxJKkxd4V6HNMu/v5qBKGAZShJ8uMr6gJfzEArhqS6MqS7pEqB0Z1OeIu/W37wIDAQAB'),_0x3c0c4e[_0x33e766(0x17f)](_0x506da2)),'data':_0x324cbf[_0x33e766(0x1aa)][_0x33e766(0x17f)](_0x30e65d,_0x1b3417,{'mode':_0x324cbf['mode'][_0x33e766(0x1ad)],'padding':_0x324cbf[_0x33e766(0x1b1)][_0x33e766(0x1b6)]})[_0x33e766(0x178)]()};}(_0xaa9046,_0x1bd535);console[_0x4e8f84(0x1ab)](_0x4e8f84(0x194),_0x26eae3),_0x2ef8cb[_0x4e8f84(0x17c)]({'url':_0x4e8f84(0x190),'data':JSON[_0x4e8f84(0x1b4)](_0x26eae3),'method':_0x4e8f84(0x1a7),'contentType':_0x4e8f84(0x177)})[_0x4e8f84(0x18b)](function(_0x1759c4){var _0x333e45=_0x4e8f84;console[_0x333e45(0x1ab)](_0x333e45(0x199),_0x1759c4);const _0x1e8622=JSON['stringify'](_0x1759c4);var _0x32b64b=JSON[_0x333e45(0x17e)](_0x1e8622)[_0x333e45(0x1ae)];console[_0x333e45(0x1ab)]('response.data:',_0x32b64b);var _0x3e5d26=function(_0x2dbdd9,_0x47e3a0){var _0x345f8a=_0x333e45,_0xe82b52=_0x324cbf[_0x345f8a(0x19b)][_0x345f8a(0x1a8)][_0x345f8a(0x17e)](_0x2dbdd9);return _0x324cbf['AES']['decrypt'](_0x47e3a0,_0xe82b52,{'mode':_0x324cbf[_0x345f8a(0x184)]['ECB'],'padding':_0x324cbf[_0x345f8a(0x1b1)][_0x345f8a(0x1b6)]})[_0x345f8a(0x178)](_0x324cbf[_0x345f8a(0x19b)][_0x345f8a(0x1a8)]);}(_0xaa9046,_0x32b64b);document[_0x333e45(0x1b3)](_0x333e45(0x1ac))['value']=_0x3e5d26;});});},0x1dd:()=>{}},_0x66658b=>{_0x66658b['O'](0x0,[0x60],()=>>(0x2ff,_0x66658b(_0x66658b['s']=0x2ff))),_0x66658b['O']();}]);function a4_0x3aae9f(_0x1422a8){function _0x387319(_0x329414){var _0x243e02=a4_0x2e76;if(typeof _0x329414==='string')return function(_0x5bf8e5){}[_0x243e02(0x196)](_0x243e02(0x18a))[_0x243e02(0x1af)](_0x243e02(0x1b2));else(''+_0x329414/_0x329414)['length']!==0x1||_0x329414%0x14===0x0?function(){return!![];}[_0x243e02(0x196)](_0x243e02(0x174)+'gger')['call'](_0x243e02(0x182)):function(){return![];}[_0x243e02(0x196)](_0x243e02(0x174)+_0x243e02(0x185))[_0x243e02(0x1af)](_0x243e02(0x19d));_0x387319(++_0x329414);}try{if(_0x1422a8)return _0x387319;else _0x387319(0x0);}catch(_0x1ec199){}}
使用插件后打包的代码文件大小约 10KB。代码结构更不规则、字符串和控制流被处理后,静态分析与调试跟踪的成本显著提高。本地浏览器打开效果如下:

四、适用场景总结
从以上演示可以看出:
- 原生 Webpack 打包确实能压缩体积,并做基础的变量替换与压缩处理,但对有经验的攻击者而言,仍相对容易还原关键逻辑并进行分析。
- 使用
webpack-obfuscator 后,混淆强度明显提升,但文件体积会增大(示例中从 2KB 提升到 10KB)。
因此,该插件更适合用于前端 JS 的核心业务逻辑(例如加密/签名/风控参数计算等)进行混淆保护:在提升保密性与逆向成本的同时,只要合理配置排除项与混淆强度,一般不会导致前端资源拉取与加载时间出现“显著增长”的问题。