数据安全一直以来是我们所追求的目标,开发的项目部署上线,有时也面临着被不法份子滥用牟利,这时我们就需要一套加密混淆软件为我们的数据、代码安全保驾护航。ProGuard就是众多混淆工具中使用较为广泛的一个。
ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性。常常在项目开发的最终用于混淆项目,增加项目被反编译的难度。
混淆工具,顾名思义只能做混淆,并不能做到真正的加密,只是增加项目被反编译的难度
springboot+maven项目使用ProGuard加密工具加密的过程如下:
在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//**-->
<!--对什么东西进行加载-->
<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
接下来你可以根据自己项目的需求去改配置中的一些内容,我能改到的一些配置比如:
自定义一个文件,用来存放自己想要的命名规则
<!--以指定文件夹中的定义格式混淆命名-->
<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下类的数量
有一些类是不允许混淆的,就单个单个的将文件列出来
就比如springboot的启动类,混淆了就找不到启动类了,所以单列出来不混淆
<!-- 单个类不混淆 -->
<option>-keep class com.ei.medical.MedicalServerApplication</option>
有一些类的类名可能会被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>-->
还有一些是不允许对类名和方法名进行混淆的,比如配置类,实体类,还有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>
还有一点,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);
}
}
现在是在pom中将需要配置的都配好了,允许不同package下存在同名文件的配置扫描也完成了,这样就可以进行操作了
直接执行maven,clean~install之后会在target文件夹下多生成三个文件
这个时候在Classes-pg.jar中就生成了混淆之后的代码,只需要拿着这些混淆的代码去顶替掉真实的代码就可以了
怎么顶替呢?
⬇
打开medical-server-1.0-SNAPSHOT.jar\BOOT-INF\classes,将此目录下的内容全部删除,将classes-pg.jar下的内容放到classes文件夹下
直接拿着混淆之后的medical-server-1.0-SNAPSHOT.jar去部署就可以了