最近在项目中碰到个一个场景,我们需要把自己的java项目jar包部署到一个第三方的服务器上,虽然双方互相信任,但是综合考虑,避免别人拿到jar包后可以很快的编译出源码,我们决定给代码加一层混淆,虽然此方法不能从根源上解决问题,但是做了一层混淆,也可以增加阅读源码的难度,总结了一下,写下这篇文章。
我用的是mac电脑,从官网: http://java-decompiler.github.io/#jd-gui-download 下载JD-GUI,官网有很多版本,下载后安装打开即可,导入你想反编译的jar,我这里随便找了个jar包做演示
细心的小伙伴肯定发现了,上面的截图有的包名是a,b,c这样命名的,但凡有点节操的程序员都不会这样命名的,这就是被混淆后的代码,让人不会一眼看出来代码里面的逻辑,效果会像下面这样
可以看到类名,包名都被修改了
我们以之前springboot项目为例,进行service层的代码的混淆,呼啸前效果如下:
接下来我们只需要在pom里面加入如下插件
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> <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> <proguardVersion>6.1.0beta2</proguardVersion> <injar>${project.build.finalName}.jar</injar> <outjar>${project.build.finalName}.jar</outjar> <obfuscate>true</obfuscate> <options> <option>-dontshrink</option> <option>-dontoptimize</option> <!-- This option will replace all strings in reflections method invocations with new class names. For example, invokes Class.forName('className')--> <option>-adaptclassstrings</option> <option>-keepdirectories</option> <!-- This option will save all original annotations and etc. Otherwise all we be removed from files.--> <option>-keepattributes Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, *Annotation*, EnclosingMethod </option> <!-- This option will save all original names in interfaces (without obfuscate).--> <option>-keepnames interface **</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>-dontusemixedcaseclassnames</option> <!-- This option will save all original class files (without obfuscate) but obfuscate all in domain and service packages.--> <option>-keep class com.stone.zplxjj.Application { public static void main(java.lang.String[]); } </option> <!-- 指明哪些类可以不被混淆--> <option>-keep class com.stone.zplxjj.autoconfiguration.** { *; }</option> <option>-keep class com.stone.zplxjj.config.** { *; }</option> <option>-keep class com.stone.zplxjj.controller.** { *; }</option> <option>-keep class com.stone.zplxjj.dao.** { *; }</option> <option>-keep class com.stone.zplxjj.entity.** { *; }</option> <option>-keep class com.stone.zplxjj.event.** { *; }</option> <option>-keep class com.stone.zplxjj.interceptor.** { *; }</option> <option>-keep class com.stone.zplxjj.listener.** { *; }</option> <option>-keep class com.stone.zplxjj.properties.** { *; }</option> <option>-keep class com.stone.zplxjj.filter.** { *; }</option> <!-- This option ignore warnings such as duplicate class definitions and classes in incorrectly named files--> <option>-ignorewarnings</option> <!-- This option will save all original class files (without obfuscate) in service package--> <!--<option>-keep class com.slm.proguard.example.spring.boot.service { *; }</option>--> <!-- This option will save all original interfaces files (without obfuscate) in all packages.--> <option>-keep interface * extends * { *; }</option> <!-- This option will save all original defined annotations in all class in all packages.--> <option>-keepclassmembers class * { @org.springframework.beans.factory.annotation.Autowired *; @org.springframework.beans.factory.annotation.Value *; } </option> </options> <injarNotExistsSkip>true</injarNotExistsSkip> <libs> <!--Put here your libraries if required--> <lib>${java.home}/lib/rt.jar</lib> </libs> </configuration> <dependencies> <dependency> <groupId>net.sf.proguard</groupId> <artifactId>proguard-base</artifactId> <version>6.1.0beta2</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin>
执行打包命令:mvn package,会看到生成如下
我们看到了生成了不只一个jar包,还有一些别的文件,这个我们放后面介绍,我们先看下划红线的jar反编译后的效果
可以看到我们针对service包下面的类混淆成功了