背景
公司代码提供给第三方使用,为了不完全泄露源码,需要对给出的代码进行加密混淆,前端代码虽然无法做到完全加密混淆,但是通过使用 webpack-obfuscator
通过增加随机废代码段、字符编码转义等方法可以使构建代码完全混淆,达到无法恢复源码甚至无法阅读的目的。
安装
webpack-obfuscator
https://www.npmjs.com/package/webpack-obfuscator
npm install --save-dev webpack-obfuscator
配置
const JavaScriptObfuscator = require ( 'webpack-obfuscator' ) ;
module. exports = {
entry: {
'abc' : './test/input/index.js' ,
'cde' : './test/input/index1.js'
} ,
output: {
path: 'dist' ,
filename: '[name].js'
} ,
plugins: [
new JavaScriptObfuscator ( {
rotateUnicodeArray: true
} , [ 'abc.js' ] )
]
} ;
vue cli
项目配置:
const path = require ( 'path' ) ;
var JavaScriptObfuscator = require ( 'webpack-obfuscator' ) ;
module. exports = {
publicPath: process. env. NODE_ENV === 'production' ? './' : '/' ,
productionSourceMap: false ,
configureWebpack: {
plugins: [
new JavaScriptObfuscator ( {
rotateStringArray: true ,
} , [ ] )
]
} ,
pwa: { } ,
pages: { }
}
若只想在打包时加密混淆,本地运行时不混淆,可以进行以下的配置:
configureWebpack: ( process. env. NODE_ENV === 'production' ) ? {
plugins: [
new JavaScriptObfuscator ( {
} , [ ] )
]
} : { } ,
vue cli 2.x
配置在 webpack.prod.conf.js
中
构建
npm run build
构建文件对比
1. 原始文件
function abc ( ) {
for ( let i = 0 ; i < 10 ; i++ ) {
console. log ( ` 第 ${ i} 个,你好,hello ` )
}
}
abc ( )
2. webpack
默认工具uglifyjs-webpack-plugin
webpackJsonp ( [ 2 ] , { lVK7 : function ( o, l ) { ! function ( ) { for ( var o= 0 ; o< 10 ; o++ ) console. log ( "第" + o+ "个,你好,hello" ) } ( ) } } , [ "lVK7" ] ) ;
3. webpack-obfuscator
无参数时
new JavaScriptObfuscator ( {
} , [ ] )
var _0x1f6e= [ "个,你好,hello" , "lVK7" , "log" ] ; ! function ( n, o ) { ! function ( o ) { for ( ; -- o; ) n. push ( n. shift ( ) ) } ( ++ o) } ( _0x1f6e, 323 ) ; var _0x3655 = function ( n, o ) { return _0x1f6e[ n-= 0 ] } ; webpackJsonp ( [ 2 ] , { lVK7 : function ( n, o ) { ! function ( ) { for ( var n= 0 ; n< 10 ; n++ ) console[ _0x3655 ( "0x0" ) ] ( "第" + n+ _0x3655 ( "0x1" ) ) } ( ) } } , [ _0x3655 ( "0x2" ) ] ) ;
4. webpack-obfuscator
高度混淆
低性能:性能比没有模糊处理慢 50-100%
new JavaScriptObfuscator ( {
compact: true ,
controlFlowFlattening: true ,
controlFlowFlatteningThreshold: 1 ,
deadCodeInjection: true ,
deadCodeInjectionThreshold: 1 ,
debugProtection: true ,
debugProtectionInterval: true ,
disableConsoleOutput: true ,
identifierNamesGenerator: 'hexadecimal' ,
log: false ,
renameGlobals: false ,
rotateStringArray: true ,
selfDefending: true ,
stringArray: true ,
stringArrayEncoding: 'rc4' ,
stringArrayThreshold: 1 ,
transformObjectKeys: true ,
unicodeEscapeSequence: false
} , [ ] ) ,
构建后文件大小: 29,999 字节(29.2 KB)
var _0xa0d1= [ "w7Bzw6oKw6E=" , "wrwIUcOVw4M=" , "w4bChi3DtcOQ" , "wpLDtsK5w4LDpA==" , "OUlQwp1z" , "woEqw4XCtsOe" , "YR3DrkDCiA==" , "woAjwq/Ci8KQ" , "dDNzw5bDgA==" ,
( "0x201" , "xatR" ) ] = function ( x ) { return x ( ) } , x[ _0x34e6 ( "0x202" , "vdcx" ) ] ( _0x2c01f8) } , 4e3 ) ;
3. webpack-obfuscator
中等混淆
最佳性能:性能比没有模糊处理慢 30-35%
new JavaScriptObfuscator ( {
compact: true ,
controlFlowFlattening: true ,
controlFlowFlatteningThreshold: 0.75 ,
deadCodeInjection: true ,
deadCodeInjectionThreshold: 0.4 ,
debugProtection: false ,
debugProtectionInterval: false ,
disableConsoleOutput: true ,
identifierNamesGenerator: 'hexadecimal' ,
log: false ,
renameGlobals: false ,
rotateStringArray: true ,
selfDefending: true ,
stringArray: true ,
stringArrayEncoding: 'base64' ,
stringArrayThreshold: 0.75 ,
transformObjectKeys: true ,
unicodeEscapeSequence: false
} , [ ] ) ,
构建后文件大小:7066字节(6.90kb)
var _0x1a25= [ "UmFzT1U=" , "RkVIc0o=" , "VUt2eW4=" , "Q29IS0g=" , "V1NSZ0k=" , "d3RNT2w=" , "dlV6cUw=" , "RlpzZWg=" , "QnpzSlE=" , "cXBqQ1k=" , "YXBwbHk=" , "bFZLNw==" , "Y3p1Ymo=" , "TFZlQXE=" , "Y2NKWlY=" , "cmV0dXJuIChmdW5jdGlvbigpIA==" ,
( b[ _0x4bcb ( "0x2a" ) ] ( "第" + c, b[ _0x4bcb ( "0x2b" ) ] ) ) } } ) } } , [ _0x4bcb ( "0x2f" ) ] ) ;
4. webpack-obfuscator
低混淆
高性能: 性能稍微慢于没有混淆
new JavaScriptObfuscator ( {
compact: true ,
controlFlowFlattening: false ,
deadCodeInjection: false ,
debugProtection: false ,
debugProtectionInterval: false ,
disableConsoleOutput: true ,
identifierNamesGenerator: 'hexadecimal' ,
log: false ,
renameGlobals: false ,
rotateStringArray: true ,
selfDefending: true ,
stringArray: true ,
stringArrayEncoding: false ,
stringArrayThreshold: 0.75 ,
unicodeEscapeSequence: false
} , [ ] ) ,
构建后文件大小: 2,424 字节(2.36 KB)
var _0x37a6= [ "exception" , "trace" , "console" , "个,你好,hello" , "lVK7" , "apply" , "return (function() " , '{}.constructor("return this")( )' , "log" , "warn" , "debug" , "info" , "error" ] ; ! function ( n, e ) { var o = function ( e ) { for ( ; -- e; ) n. push ( n. shift ( ) ) } ;
[ _0xe1fd ( "0x3" ) ] ( "第" + n+ _0xe1fd ( "0xb" ) ) } ( ) } } , [ _0xe1fd ( "0xc" ) ] ) ;
对比表格
文件名称
文件大小
正常构建
无参数
高度混淆
中度混淆
低度混淆
test.js
117字节
177字节
363字节
29.2 KB(29,999 字节)
6.90KB(7066字节)
2.36 KB(2,424 字节)
jquery.js
111 KB (113,852 字节)
85.0 KB (87,064 字节)
115 KB (117,770 字节)
1.24 MB (1,304,998 字节)
401 KB (411,543 字节)
117 KB (120,243 字节)
主要属性
{
compact: true ,
controlFlowFlattening: false ,
controlFlowFlatteningThreshold: 0.75 ,
deadCodeInjection: false ,
deadCodeInjectionThreshold: 0.4 ,
debugProtection: false ,
debugProtectionInterval: false ,
disableConsoleOutput: false ,
domainLock: [ ] ,
identifierNamesGenerator: 'hexadecimal' ,
identifiersPrefix: '' ,
inputFileName: '' ,
log: false ,
renameGlobals: false ,
reservedNames: [ ] ,
reservedStrings: [ ] ,
rotateStringArray: true ,
seed: 0 ,
selfDefending: false ,
sourceMap: false ,
sourceMapBaseUrl: '' ,
sourceMapFileName: '' ,
sourceMapMode: 'separate' ,
stringArray: true ,
stringArrayEncoding: false ,
stringArrayThreshold: 0.75 ,
target: 'browser' ,
transformObjectKeys: false ,
unicodeEscapeSequence: false
}
注意
安装 webpack-obfuscator
时要注意webpack-obfuscator
的版本要与本地项目 webpack
版本相匹配,我用的是webpack-obfuscator@0.18.0
项目 webpack
是 4.x
版本。(4.x版
本 webpack
使用最新版 webpack-obfuscator@3.3.0
会报错无法使用,webpack
杳升级到 5.x
版本)。
excludes数组
的兼容 multimatch包语法
,例如支持 ['js/chunk-vendors.**.js']
、 ['excluded_bundle_name.js', '**_bundle_name.js']
或 'excluded_bundle_name.js'
等。
文章地址:https://www.cnblogs.com/dragonir/p/14445767.html 作者:dragonir