Springboot+proguard+maven 混淆代码

       最近开发的项目要进行试点,为了防止代码很容易被反编译而造成泄露,故而进行了代码混淆的研究,而项目中又时使用spring boot框架开发的,经过网上找的资料以及自己的实验,终于将代码进行了最大程度的混淆,特在此记录一下,与诸位分享。

       我混淆代码使用的是proguard-maven-plugin这个插件,所有proguard的指令都可以在pom中实现。首先要说的是通过这种方法混淆就是移除没有用到的代码,然后对代码里面的类、变量、方法重命名为人可读性很差的简短名字,比如a,b,c等,所以如果这种程度的混淆无法满足你的需求,还是寻找其他混淆方法,如加密等。

       接下来将进行具体如何混淆。首先,整个混淆在pom文件中引入proguard-maven-plugin这个插件,并在pom文件中进行混淆的具体配置即可,pom配置示例如下:

<build>
	<plugins>
		<plugin>
			<groupId>com.github.wvengen</groupId>
			<artifactId>proguard-maven-plugin</artifactId>
			<version>2.0.11</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>
					<!-- 不做收缩(删除注释、未被引用代码) -->
					<option>-dontshrink</option>
					<!-- 不做优化(变更代码实现逻辑) -->
					<option>-dontoptimize</option>
					<!-- 不路过非公用类文件及成员 -->
					<option>-dontskipnonpubliclibraryclasses</option>
					<option>-dontskipnonpubliclibraryclassmembers</option>
					<!-- 优化时允许访问并修改有修饰符的类和类的成员 -->
					<option>-allowaccessmodification</option>
					<!-- 确定统一的混淆类的成员名称来增加混淆 -->
					<option>-useuniqueclassmembernames</option>
					<!-- 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有 
                    大量固定写法的包名 -->
					<option>-keeppackagenames</option>
					<option>-adaptclassstrings</option>
					<!-- <option>-keepdirectories</option> -->
					<!-- 不混淆所有特殊的类 -->
					<option>-keepattributes
						Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>
					<!-- This option will save all original methods parameters in files 
		defined in -keep sections, otherwise all parameter names will be obfuscate. -->
					<option>-keepparameternames</option>
					<option>-keepclassmembers class * {
						@org.springframework.beans.factory.annotation.Autowired *;
						@org.springframework.beans.factory.annotation.Value *;
						}
					</option>

					<option>-keep class !com.example.** { *; }</option>
					<!-- 不混淆main方法 -->
					<option>-keep class com.example.Application { *; }</option>

					<!-- 不混淆所有的set/get方法 -->
					<option>-keepclassmembers public class * {void set*(***);***
							get*();}</option>
					<!-- 不混淆包中的所有类以及类的属性及方法,实体包,混淆了会导致ORM框架及前端无法识别 -->

					<!-- 不对包类的类名进行混淆,但对类中的属性和方法混淆 -->
					<option>-keep class com.example.controller.** </option>
					<option>-keep class com.example.service.** </option>
					<option>-keep class com.example.scheduling.** </option>

					<!-- 不混淆包下的所有类名,且类中的方法也不混淆 -->
					<option>-keep class com.example.redis.** {*;}</option>
					<option>-keep class com.example.kafka.config.**{*;}</option>
					<option>-keep class com.example.pojo.** {*;}</option>
					<option>-keep class
					com.example.systemList.dto.** {*;}</option>
					<option>-keep class com.example.dto.** {*;} </option>
					<option>-keep class com.example.configure.**{*;}</option>
					<option>-keep class com.example.dao.** {*;}</option>

				</options>
				<outjar>${project.build.finalName}-pg.jar</outjar>
					<!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 -->
				<libs>
					<lib>${java.home}/lib/rt.jar</lib>
					<lib>${java.home}/lib/jce.jar</lib>
				</libs>

				<injar>classes</injar>
				<!-- 输出目录 -->
				<outputDirectory>${project.build.directory}</outputDirectory>
			</configuration>
		</plugin>



	</plugins>
</build>

       使用时将上面pom文件中的plugin标签中的内容引入到自己的pom文件中,将具体的包名换成自己的即可。具体的配置注释中都有,使用过程中主要难点是每个包可混淆到哪种程度,具体的情况需要时最好可以自行进行实验进行验证。下面我将我的混淆配置讲解一下:

  • <option>-keep class !com.example.** { *; }</option> 是混淆这个包下的类
  • 对于controller、service以及定时任务这三个包,我采用的混淆程度为不对类名进行混淆,但是对属性和方法进行混淆
  • 对于dao、pojo、dto以及配置类的包,我不进行混淆

       以上的配置是我自己经过一次次尝试发现的所能混淆的最大程度,否则会报错。注意,在proguard-maven-plugin中默认是对类名,属性,方法全部混淆,所以如果全部混淆,则不需要配置这个包即可。我个人的感悟是混淆的程度主要是由于很多类是交由spring管理,所以这些spring bean的类名以及所注入的对象(由spring管理)最好不要混淆类名,否则spring无法识别以及管理,另外就是DAO类,如果是MySQL这种通过Mapper的XML文件映射的类型,最好不要混淆,否则DAO无法找到对应的SQL语句,其他例如Hbase等通过代码查询,读者可尝试进行混淆。一些工具包也是可以进行混淆的,混淆到那种程度读者可进行尝试。

       完成上述配置后,便可以执行maven命令进行打包,最终在target目录下会生成自己项目的jar包以及一个classes-pg.jar的jar包,其中自己项目的jar包是没有混淆代码的jar包,而classes-pg.jar包中的内容才是真正混淆后的代码,将项目的jar包用winrar打开(切记不饿能解压,否则jar包无法运行),进入到classes目录下,将classes-pg.jar中的内容(不包括META-INF文件夹)复制到项目的jar包的classes目录下即可,这样最后的项目的jar包便是进行代码混淆后的jar包,读者可自行反编译观察一下代码混淆的效果,如果启动后报错,读者可根据错误信息修改混淆的类即可。另外这里有一篇博客写的挺详细的,读者也可以看一下博文地址。如果报错的内容是类名冲突之类的,可以尝试一下在启动类中加入下面的代码:

public static class CustomGenerator implements BeanNameGenerator {
		 
        @Override
        public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
            return definition.getBeanClassName();
        }
}

将每个类名前加入包名,这样基本不会冲突了。至此,代码混淆完成,有问题的我们可以一起交流。

       程序之路漫漫,吾将上下而求索

 

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页