1. Java代码混淆的背景
1.1 混淆使用场景
我们在工程应用中经常会遇到核心代码不希望给别人抄袭,但系统是用java开发的,无法避免被反编译的情况,这样可以用代码混淆的方式来解决。调查了一下主流的第三方混淆工具,目前主流的有三种技术yguard、ProGuard、Allatori,我们目前方案就是采用Allatori进行Java的代码混淆。
1.2 Allatori简介
allatori官方网站:https://allatori.com/
proguard官网: https://www.guardsquare.com/proguard.
2. 混淆的插件的集成
2.1 操作流程
(以auth-serivce服务为例)
- 在auth-service服务下建立allatori文件夹
- 将官网下载的lib文件夹拷贝到allatori文件夹下
- 新建allatori.xml文件(log.xml文件在package的时候会自动生成)
<config>
<input>
<!--混淆后直接覆盖原文件,out指向的路劲为混淆后的jar -->
<jar in="../app/lib/service-deadline-control-sca-boot-starter-1.5.1-SNAPSHOT.jar"
out="../app/lib/service-deadline-control-sca-boot-starter-1.5.1-SNAPSHOT.jar"/>
</input>
<classpath>
<jar name="../app/lib/*.jar"/>
</classpath>
<keep-names>
<!-- <class access="protected+">-->
<!-- <field access="protected+" />-->
<!-- <method access="protected+" />-->
<!-- </class>-->
<class template="class com.aaa.sca.config.ServiceDeadlineControlConfiguration"></class>
<class template="class com.aaa.sca.constant.ServiceDeadlineControlConstants"></class>
<class template="class com.aaa.sca.model.*"></class>
<class template="class com.aaa.sca.runner.AuthCodeApplicationRunner"></class>
<class template="class com.aaa.sca.scheduler.ServiceCertificateReloadScheduler"></class>
<class template="class com.aaa.sca.service.ServiceCertificateService"></class>
<class template="class com.aaa.sca.util.*"></class>
<!-- Matches serialization members -->
<!-- <class template="class * instanceof java.io.Serializable">-->
<!-- <field template="static final long serialVersionUID"/>-->
<!-- <method template="void writeObject(java.io.ObjectOutputStream)"/>-->
<!-- <method template="void readObject(java.io.ObjectInputStream)"/>-->
<!-- <method template="java.lang.Object writeReplace()"/>-->
<!-- <method template="java.lang.Object readResolve()"/>-->
<!-- </class>-->
</keep-names>
<ignore-classes>
<!-- 配置启动类不被混淆 保证springBoot可以正常启动 -->
<!-- <class template="class *ServiceDeadlineControlConfiguration*"/>-->
<class template="class com.aaa.sca.config.ServiceDeadlineControlConfiguration"></class>
<class template="class com.aaa.sca.model.AuthCodeContent"></class>
<class template="class com.aaa.sca.model.ServiceCertificate"></class>
<!-- 第三方的 不需要混淆 -->
<class template="class *springframework*"/>
<class template="class *spring*"/>
<class template="class *framework*"/>
<class template="class *alibaba*"/>
<class template="class *persistence*"/>
<class template="class *apache*"/>
<!-- 排除如下包下的类-->
<!-- <class template="class com.sinohealth.sca.config.*"/>-->
</ignore-classes>
<property name="log-file" value="../allatori/log.xml"/>
<!-- <property name="packages-naming" value="abc"/>-->
<property name="classes-naming" value="abc"/>
<property name="classes-naming" value="unique"/>
<property name="fields-naming" value="123"/>
<property name="fields-naming" value="iii"/>
<property name="string-encryption" value="enable"/>
<property name="string-encryption-type" value="fast"/>
<property name="string-encryption-version" value="v4"/>
</config>
-
在项目的pom.xml新增pulgin依赖
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-and-filter-allatori-config</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target</outputDirectory> <resources> <resource> <directory>allatori</directory> <includes> <include>allatori.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <id>run-allatori</id> <phase>package</phase> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>java</executable> <arguments> <argument>-Xms128m</argument> <argument>-Xmx512m</argument> <argument>-jar</argument> <argument>allatori/lib/allatori.jar</argument> <argument>${basedir}/target/allatori.xml</argument> </arguments> </configuration> </plugin>
2.2 混淆的配置说明
allatori.xml为allatori插件的混淆配置
<input>
<!--混淆后直接覆盖原文件,out指向的路劲为混淆后的jar -->
<jar in="../app/lib/service-deadline-control-sca-boot-starter-1.5.1-SNAPSHOT.jar"
out="../app/lib/service-deadline-control-sca-boot-starter-1.5.1-SNAPSHOT.jar"/>
</input>
in是未混淆的jar的输入路径, out是混淆后的jar输出路径
<classpath>
<jar name="../app/lib/*.jar"/>
</classpath>
classpath是jar依赖的相关jar
<keep-names>
<class access="protected+">
<field access="protected+" />
<method access="protected+" />
</class>
<class template="class com.aaaa.sca.config.ServiceDeadlineControlConfiguration"></class>
</keep-names>
class 指定保持不变的类名,配置类保持,不然springboot加载会有问题
field 指定保持不变的属性名
method 指定保持不变的方法名
<ignore-classes>
<!-- 配置启动类不被混淆 保证springBoot可以正常启动 -->
<!-- <class template="class *ServiceDeadlineControlConfiguration*"/>-->
<class template="class com.aaa.sca.config.ServiceDeadlineControlConfiguration"></class>
<class template="class com.aaa.sca.model.AuthCodeContent"></class>
<class template="class com.aaa.sca.model.ServiceCertificate"></class>
<!-- 第三方的 不需要混淆 -->
<class template="class *springframework*"/>
<class template="class *spring*"/>
<class template="class *framework*"/>
<class template="class *alibaba*"/>
<class template="class *persistence*"/>
<class template="class *apache*"/>
<!-- 排除如下包下的类-->
</ignore-classes>
ignore-classes是指定完全不混淆的class
2.3 校验混淆结果
- 执行maven指令,进行打包,如果看到一下日志,说明打包成功;
mvn clean install -Dmaven.test.skip=true
-
使用jd-gui工具反编译jar包,查看代码,看到以下效果就是混淆成功了;
-
启动项目是否正常,查看日志是否正常,各方面政策则完成混淆可以直接推代码到测试环境运行;
参考博客:
https://blog.youkuaiyun.com/lonelymanontheway/article/details/104574050/
https://blog.youkuaiyun.com/blackoon88/article/details/124630907