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
})
  1. 添加混淆配置
// 混淆配置
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. 遍历 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);
      });
    })
  })
}
  1. 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. 在打包后的文件中搜索是否还存在相关敏感信息

以上!

posted @ 2022-06-16 16:03  blackbentel  阅读(1965)  评论(0编辑  收藏  举报