数据安全一直以来是我们所追求的目标,开发的项目部署上线,有时也面临着被不法份子滥用牟利,这时我们就需要一套加密混淆软件为我们的数据、代码安全保驾护航。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//**</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接下来你可以根据自己项目的需求去改配置中的一些内容,我能改到的一些配置比如:
-
自定义一个文件,用来存放自己想要的命名规则
<!--以指定文件夹中的定义格式混淆命名--> <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就是生成的混淆文件
- proguard_map为混淆的类名/方法的对应关系
- proguard_seed为参与混淆的类
-
这个时候在Classes-pg.jar中就生成了混淆之后的代码,只需要拿着这些混淆的代码去顶替掉真实的代码就可以了
怎么顶替呢?
⬇
打开medical-server-1.0-SNAPSHOT.jar\BOOT-INF\classes,将此目录下的内容全部删除,将classes-pg.jar下的内容放到classes文件夹下这样就完成了代码的混淆
-
直接拿着混淆之后的medical-server-1.0-SNAPSHOT.jar去部署就可以了