springboot+maven项目使用ProGuard混淆工具的步骤

数据安全一直以来是我们所追求的目标,开发的项目部署上线,有时也面临着被不法份子滥用牟利,这时我们就需要一套加密混淆软件为我们的数据、代码安全保驾护航。ProGuard就是众多混淆工具中使用较为广泛的一个。

ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常在项目开发的最终用于混淆项目,增加项目被反编译的难度。

混淆工具,顾名思义只能做混淆,并不能做到真正的加密,只是增加项目被反编译的难度

springboot+maven项目使用ProGuard加密工具加密的过程如下:

  1. 在springboot项目的pom.xml文件中,引入插件相关依赖

    <build>
        <plugins>
        	<plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.0.14</version>
                <executions>
                    <execution>
                        <!--混淆时刻,这里是打包的时候混淆-->
                        <phase>package</phase>
                        <goals>
                            <!--使用插件的什么功能,当然是混淆-->
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!--是否将生成的PG文件安装部署-->
                    <attach>true</attach>
                    <!--是否混淆-->
                    <obfuscate>true</obfuscate>
                    <!--指定生成文件分类-->
                    <attachArtifactClassifier>pg</attachArtifactClassifier>
                    <options>
                        <!--JDK目标版本1.8-->
                        <option>-target 1.8</option>
                        <!--压缩是默认开启的。压缩会删除没有使用的类以及类成员,除了由各种“-keep”选项列出的类和它们直接或间接依赖的类-->
                        <!--关闭收缩-->
                        <option>-dontshrink</option>
                        <!--优化是默认情况下启用的;。所有方法都在字节码级进行优化-->
                        <!--关闭优化(变更代码实现逻辑)-->
                        <option>-dontoptimize</option>
                        <!--不路过非公用类文件及成员-->
                        <option>-dontskipnonpubliclibraryclasses</option>
                        <option>-dontskipnonpubliclibraryclassmembers</option>
                        <!--优化时允许访问并修改有修饰符的类和类的成员-->
                        <option>-allowaccessmodification</option>
                        <!--以指定文件夹中的定义格式混淆命名,自定义一个filename.txt文件用来存放你自己想要的命名规则-->
                        <option>-classobfuscationdictionary filename.txt</option>
                        <!--确定统一的混淆类的成员名称来增加混淆,防止冲突-->
                        <option>-useuniqueclassmembernames</option>
                        <!--不混淆所有包名,Spring配置中有大量固定写法的包名-->
                        <option>-keeppackagenames</option>
                        <!--不混淆所有特殊的类-->
                        <option>
                            -keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
                        </option>
                        <!--不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射-->
                        <option>-keepclassmembers public class *{
          
          void set*(***);*** get*();}</option>
    
    					<!-- 单个类不混淆 -->
                        <option>-keep class com.ei.medical.MedicalServerApplication</option>
                        
                        <!-- 不对包类的类名进行混淆,但对类中的属性和方法混淆 -->
                        <option>-keep class com.ei.medical.component.**</option>
                        <option>-keep class com.ei.medical.exception.** </option>
                        <!--<option>-keep class com.ei.medical.modules.appController.** </option>-->
                        <!--<option>-keep class com.ei.medical.modules.client.** </option>-->
                        <!--<option>-keep class com.ei.medical.modules.controller.** </option>-->
                        <!--<option>-keep class com.ei.medical.modules.mapper.** </option>-->
                        <!--<option>-keep class com.ei.medical.modules.service.** </option>-->
                        <!--<option>-keep class com.ei.medical.modules.temp.** </option>-->
                        <!--<option>-keep class com.ei.medical.utils.** </option>-->
                        <!--<option>-keep class com.ei.medical.websocket.** </option>-->
                        
                        <!-- 不混淆包下的所有类名,且类中的方法也不混淆 -->
                        <option>-keep class com.ei.medical.modules.mapper.** {
          
          *;}</option>
                        <option>-keep class com.ei.medical.modules.temp.mapper.** {
          
          *;} </option>
                        <option>-keep class com.ei.medical.modules.vo.** {
          
          *;}</option>
                        <option>-keep class com.ei.medical.config.** {
          
          *;}</option>
                        
                        <!--不显示警告信息,如果显示则会出现Error无法完成混淆-->
                        <option>-ignorewarnings</option>
    				</options>
    				
    				<!--输出混淆后的jar的名称-->
                    <outjar>${
          
          project.build.finalName}-pg.jar</outjar>
                    <!--添加依赖,这里你可以按你的需要修改,这里只需要一个JRE的Runtime包就行了-->
                    <libs>
                        <lib>${
          
          java.home}/lib/rt.jar</lib>
                    </libs>
                    <!--加载文件的过滤器,就是你的工程目录了-->
                    <!--<inFilter>com/ei/medical//**</inFilter>-->
                    <!--对什么东西进行加载-->
                    <injar>classes</injar>
                    <!--输出目录-->
                    <outputDirectory>${
          
          project.build.directory}</outputDirectory>
                </configuration>
                <dependencies>
                    <!--使用6.0.2版本来混淆-->
                    <dependency>
                        <groupId>net.sf.proguard</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>6.0.2</version>
                        <scope>compile</scope>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    

    这个文件太长了,一个框竟然放不下

    其中每一条配置的含义都有注释,如果感觉有疑惑的,可以去下面文章中去看看

    https://www.jianshu.com/p/b471db6a01af
    or
    https://my.oschina.net/JiangTun/blog/1839302

    接下来你可以根据自己项目的需求去改配置中的一些内容,我能改到的一些配置比如:

    1. 自定义一个文件,用来存放自己想要的命名规则

      <!--以指定文件夹中的定义格式混淆命名-->
      <option>-classobfuscationdictionary filename.txt</option>
      

      我的文件中存放的内容如下

      a0
      a1
      a2
      a3
      a4
      a5
      a6
      a7
      a8
      a9
      a00
      a11
      a22
      a33
      a44
      a55
      a66
      a77
      a88
      a99
      a000
      a111
      a222
      a333
      a444
      a555
      a666
      a777
      a888
      a999
      a0000
      a1111
      a2222
      a3333
      a4444
      a5555
      a6666
      a7777
      a8888
      a9999
      a00000
      a11111
      a22222
      a33333
      a44444
      a55555
      a66666
      a77777
      a88888
      a99999
      a000000
      a111111
      a222222
      a333333
      a444444
      a555555
      a666666
      a777777
      a888888
      a999999
      

      就随便写,你越混淆代码越混淆,混淆中的战斗混淆

      有一点是挺重要的,就是自定义文件中字段的数量要大于最大的package下类的数量

    2. 有一些类是不允许混淆的,就单个单个的将文件列出来
      就比如springboot的启动类,混淆了就找不到启动类了,所以单列出来不混淆

      <!-- 单个类不混淆 -->
      <option>-keep class com.ei.medical.MedicalServerApplication</option>
      
    3. 有一些类的类名可能会被spring加载用以一些配置,所以也是不可以混淆的,但是类中的方法可以混淆,可以用这种方式,xxxx.**是保留类名,不保留方法
      就比如utils中的类

      <!-- 不对包类的类名进行混淆,但对类中的属性和方法混淆 -->
      <option>-keep class com.ei.medical.component.**</option>
      <option>-keep class com.ei.medical.exception.** </option>
      <!--<option>-keep class com.ei.medical.modules.appController.** </option>-->
      <!--<option>-keep class com.ei.medical.modules.client.** </option>-->
      <!--<option>-keep class com.ei.medical.modules.controller.** </option>-->
      <!--<option>-keep class com.ei.medical.modules.mapper.** </option>-->
      <!--<option>-keep class com.ei.medical.modules.service.** </option>-->
      
    4. 还有一些是不允许对类名和方法名进行混淆的,比如配置类,实体类,还有mapper,因为 .xml文件是没办法混淆的,所以和xml对应的类、其中引入的方法和实体也是不可以混淆的, xxxx.** {*;}是保留类名也保留方法
      例如实体类、mapper、config

      <!-- 不混淆包下的所有类名,且类中的方法也不混淆 -->
      <option>-keep class com.ei.medical.modules.mapper.** {
              
              *;}</option> 
      <option>-keep class com.ei.medical.modules.temp.mapper.** {
              
              *;} </option> 
      <option>-keep class com.ei.medical.modules.vo.** {
              
              *;}</option> 
      <option>-keep class com.ei.medical.config.** {
              
              *;}</option>
      
  2. 还有一点,pom文件虽然配置好了,但是这个时候每个package下的类都是按照自定义的文件中的字段进行命名的,也就是说不同的package下类的类名都是一样的,所以启动的时候会报错,为了保证不同package下允许存在同名的类,需要对springboot进行添加配置

    自定义一个配置文件

    public class UniqueNameGenerator extends AnnotationBeanNameGenerator {
          
          
    
        @Override
        public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
          
          
            //全限定类名
            String beanName = definition.getBeanClassName();
            return beanName;
        }
    }
    

    然后在启动类上添加扫描此配置文件

    @SpringBootApplication
    @ComponentScan(nameGenerator = UniqueNameGenerator.class)
    public class MedicalServerApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(MedicalServerApplication.class, args);
        }
    }
    
  3. 现在是在pom中将需要配置的都配好了,允许不同package下存在同名文件的配置扫描也完成了,这样就可以进行操作了
    直接执行maven,clean~install之后会在target文件夹下多生成三个文件

    1. Classes-pg.jar就是生成的混淆文件
    2. proguard_map为混淆的类名/方法的对应关系
    3. proguard_seed为参与混淆的类
      target
  4. 这个时候在Classes-pg.jar中就生成了混淆之后的代码,只需要拿着这些混淆的代码去顶替掉真实的代码就可以了
    怎么顶替呢?

    打开medical-server-1.0-SNAPSHOT.jar\BOOT-INF\classes,将此目录下的内容全部删除,将classes-pg.jar下的内容放到classes文件夹下

    这样就完成了代码的混淆
    顶替

  5. 直接拿着混淆之后的medical-server-1.0-SNAPSHOT.jar去部署就可以了

猜你喜欢

转载自blog.csdn.net/weixin_45121502/article/details/105708152