目录
一、需求背景
二、具体实现
一、需求背景
某些情况下需要将jar包交付给第三方,担心第三方会将代码进行反编译,故需要将jar包进行处理。
jar包源码混淆工具有多种,但真正能投入使用的产品并不多。
比如 ClassFinal (ClassFinal: Java字节码加密工具),国内开发者做的jar包加密工具,已经停止维护好几年了,它需要另外提供一个加密包做处理。它其实是一个加密方案,更注重安全性,但它并不是一个很好的使用方案。毕竟jvm的特点就是可移植性,本身就应该是一个容易使用的东西,谁还愿意带个“挂件”走呢?
Proguard(GitHub - Guardsquare/proguard: ProGuard, Java optimizer and obfuscator) 混淆源码的作用在于能够在不影响服务能力的前提下紊乱jar包内的源码,能够极大的降低代码可读性。对于研发而言,反编译后使用的成本过高,还不如直接自己重新写,所以它其实也算是满足了代码安全性的要求。
需要注意的是,它是一个java产品,并不是一个spring的产品,所以它对spring相关注解并不支持,它并不会特殊对待springboot。但是现有的java项目有几个不是spring?所以它很需要开发人员进行定制化处理,这块的成本很高,特别是对于不熟悉这项产品的开发人员。
这里尽量提供一个最简单、最直接、开箱可用的使用方案。
二、具体实现
Proguard核心内容是两个配置文件,一个pom.xml、一个proguard.cfg,这里提供最关键的两个能够直接使用的配置文件内容,其余的配置相关描述可以通过文末的参考文献获取。
pom.xml 配置文件 (注意:它必须要放到spring-boot-maven-plugin上面):
<plugin><groupId>com.github.wvengen</groupId><artifactId>proguard-maven-plugin</artifactId><version>2.5.3</version><executions><execution><phase>package</phase><goals><goal>proguard</goal></goals></execution></executions><configuration><proguardVersion>${proguard.version}</proguardVersion><injar>${project.build.finalName}.jar</injar><outjar>${project.build.finalName}.jar</outjar><obfuscate>true</obfuscate><proguardInclude>${project.basedir}/proguard.cfg</proguardInclude><libs><lib>${java.home}/lib/rt.jar</lib><lib>${java.home}/lib/jce.jar</lib></libs></configuration><dependencies><dependency><groupId>com.guardsquare</groupId><artifactId>proguard-base</artifactId><version>7.2.1</version></dependency></dependencies>
</plugin>
proguard.cfg:
-target 1.8
-keepdirectories
-dontoptimize#不做收缩,这个参数很关键,否则会丢掉一些源码,springboot很多组件会受影响
-dontshrink-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod,MethodParameters-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers#混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
-allowaccessmodification#对于类成员的命名的混淆采取唯一策略
-useuniqueclassmembernames#保留包名
-keeppackagenames#保留Serializable序列化的类不被混淆
#例如传入/输出的Bean属性
-keepclassmembers class * implements java.io.Serializable {*;}-keepnames interface ** { *; }
-keep interface * extends * { *; }
-keepclassmembers enum * { *; }-keepclassmembers class * {@org.springframework.context.annotation.Bean *;@org.springframework.beans.factory.annotation.Autowired *;@org.springframework.beans.factory.annotation.Value *;@org.springframework.stereotype.Service *;@org.springframework.stereotype.Component *;
}-keep @org.aspectj.lang.annotation.Aspect class *{*;}#应用特性不能被混淆的代码
-keep public class com.mgtv.mcp.RunApplication {*;}
-keep class com.mgtv.mcp.annotation.** {*;}
-keep class com.mgtv.mcp.common.** {*;}
-keep class com.mgtv.mcp.config.** {*;}
-keep class com.mgtv.mcp.converter.** {*;}
-keep class com.mgtv.mcp.pojo.** {*;}
-keep class com.mgtv.mcp.controller.** {*;}
-keep class com.mgtv.mcp.dao.** {*;}
-keep class com.mgtv.mcp.provider.model.** {*;}
-keep class com.mgtv.mcp.provider.request.** {*;}
-keepclassmembers class com.mgtv.mcp.controller.** {*;}#-ignorewarnings
参考文献:
https://www.cnblogs.com/strongmore/p/18026443
https://blog.51cto.com/u_13675550/6077539