webpack2 webpack 3 低版本混淆代码打包
webpack2 webpack 3 低版本混淆代码打包
概要
- 本文档适用 webpack@2+,当然也是适用于 webpack@4 以上版本,vue-cli3+ 或者 webpack@4 推荐这篇 vue 项目代码混淆
- 上个文档适用于webpack@4+的项目混淆,因为 webpack-obfuscator 最低适配 webpack@4
- 原理: 直接使用 javascript-obfuscator 插件混淆文件,并在打包时使用混淆后文件替代源文件,实现混淆敏感信息
基本步骤
1. 引入javascript-obfuscator
webpack@4- 使用 javascript-obfuscator@2.6.0 版本
cnpm i javascript-obfuscator@2.6.0 -D
2. 单独出来文件编写混淆相关方法 obfuscator.js
1)整理需要混淆的文件路径,并在同目录生成混淆后新文件的路径,这里的-needObfuscate
后面会用到
// 需要混淆的文件列表
const encryptFiltList = [
{
oldFilePath: path.resolve(__dirname, 'src/app/xxx-needObfuscate.js')
},
{
oldFilePath: path.resolve(__dirname, 'src/app/bbb-needObfuscate.js')
},
].map(item => {
item.newFilePath = item.oldFilePath.replace('-needObfuscate.js', '-obfuscated.js')
return item
})
- 添加混淆配置
// 混淆配置
const obfuscatorConfig = {
compact: true,//压缩代码
controlFlowFlattening: false,//是否启用控制流扁平化(降低1.5倍的运行速度)
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转义序列大大增加了代码大小,并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
}
- 遍历 1)中的文件列表混淆后生成新的文件
const FS = require('fs')
const JavaScriptObfuscator = require('javascript-obfuscator');
module.exports = function () {
// 遍历需要混淆的文件列表
encryptFiltList.forEach(item => {
console.log('混淆文件-----', item.oldFilePath);
// 读取文件内容
FS.readFile(item.oldFilePath, function (err,data) {
if (err) {
return err
}
let str = data.toString()
// 使用JavaScriptObfuscator 混淆文件内容后放进新文件路径下
const result = JavaScriptObfuscator.obfuscate(str, obfuscatorConfig).getObfuscatedCode()
FS.writeFile(item.newFilePath, result, function (err) {
if (err) return err;
console.log('混淆完成-----', item.newFilePath);
});
})
})
}
- obfuscator.js 完整内容如下
const FS = require('fs')
const JavaScriptObfuscator = require('javascript-obfuscator');
/* 混淆部分文件 */
// 需要混淆的文件列表
const encryptFiltList = [
{
oldFilePath: path.resolve(__dirname, 'src/app/xxx-needObfuscate.js')
},
{
oldFilePath: path.resolve(__dirname, 'src/app/bbb-needObfuscate.js')
},
].map(item => {
item.newFilePath = item.oldFilePath.replace('-needObfuscate.js', '-obfuscated.js')
return item
})
// 混淆配置
const obfuscatorConfig = {
compact: true,//压缩代码
controlFlowFlattening: false,//是否启用控制流扁平化(降低1.5倍的运行速度)
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转义序列大大增加了代码大小,并且可以轻松地将字符串恢复为原始视图。建议仅对小型源代码启用此选项。
}
module.exports = function () {
// 遍历需要混淆的文件列表
encryptFiltList.forEach(item => {
console.log('混淆文件-----', item.oldFilePath);
// 读取文件内容
FS.readFile(item.oldFilePath, function (err,data) {
if (err) {
return err
}
let str = data.toString()
// 使用JavaScriptObfuscator 混淆文件内容后放进新文件路径下
const result = JavaScriptObfuscator.obfuscate(str, obfuscatorConfig).getObfuscatedCode()
FS.writeFile(item.newFilePath, result, function (err) {
if (err) return err;
console.log('混淆完成-----', item.newFilePath);
});
})
})
}
4. 在 webpack 中调用上面写的混淆方法
- 引用 obfuscator.js 并调用其方法,记得判断生产环境,开发环境没有必要混淆
- 每个项目判断生产的方法可能不一样,这里将
isProd
更改成自己项目判断生产的方式
const obfuscator = require('./obfuscator')
if (isProd) {
obfuscator()
}
5. !!!重要:使用 webpack.NormalModuleReplacementPlugin
更换需要混淆文件的引用路径
- 将如下代码放进 webpack 的 plugins 中
- 作用:在webpack 打包时如果遇到引入路径中包含
-needObfuscate
时,就会将其引入路径中的-needObfuscate
改为-obfuscated
,也就是改为混淆后的路径
// 需要混淆的文件需要将源文件更换为混淆后的文件
new webpack.NormalModuleReplacementPlugin(/(.*)-needObfuscate(\.*)/, function(resource) {
resource.request = resource.request.replace(/-needObfuscate/, `-obfuscated`);
})
6. 在 .gitignore
文件中添加配置排除混淆后的文件
- 混淆后的文件日常开发中用不到,也不需要提交到git仓库,所以在 .gitignore 中添加其路径将其排除
*-obfuscated.js
7. 在打包后的文件中搜索是否还存在相关敏感信息
以上!