Springboot使⽤ProGuard实现代码混淆
代码混淆常见于安卓的apk安装⽂件, 服务端的代码因为不易被普通⽤户接触到, 所以混淆不多。但是某些场景下, ⽐如:项⽬需要部署到客户机器上, 就会有泄露代码逻辑的风险。
不过需要知道的是:使⽤proguard混淆代码只能增加阅读和理解的难度, 并不能百分百保证代码安全。也即是达到让开发⼈员看到这头痛的代码有99.99999%的冲动放弃阅读,拍桌⼦说还不如我重写⼀遍逻辑。
⼀、 ProGuard简介
附:proGuard官⽹
因为Java代码是⾮常容易反编译,况且Springboot和Android开发的应⽤程序都是⽤Java代码写的,为了很好的保护Java源代码,我们需要对编译好后的class⽂件进⾏混淆。
ProGuard是⼀个混淆代码的开源项⽬,它的主要作⽤是混淆代码,殊不知ProGuard还包括以下4个功能:
1. 压缩(Shrink):检测并移除代码中⽆⽤的类、字段、⽅法和特性(Attribute)。
2. 优化(Optimize):对字节码进⾏优化,移除⽆⽤的指令。
3. 混淆(Obfuscate):使⽤a,b,c,d这样简短⽽⽆意义的名称,对类、字段和⽅法进⾏重命名。
4. 预检(Preveirfy):在Java平台上对处理后的代码进⾏预检,确保加载的class⽂件是可执⾏的。
⼆、混淆配置要点
1. 建议逐个java包定义混淆规则,这样思路更清晰 ;
2. repository(dao)层需要保存包名和类名,因为Mybatis的xml⽂件中引⽤了dao层的接⼝ ;
3. controller层注意在使⽤@PathVariable、@RequestParam时需要显式声明参数名 ;
4. dao层⽤于映射数据库表的类和controller层映射前台参数的类,都需要保留类成员 ;
5. 修改spring的bean命名策略,改成按类的全限定名来命名。
三、快速开始
本⽂基于springboot2.x + maven + proguard进⾏代码混淆。
将源码打包做代码混淆还有其他⽅案,但是没成功,最终选择proguard,开始使⽤遇到各种问题,各种jar包版本问题,尝试了5次不同⽅案,费了⼗⽜⼆虎之⼒最终成功,Mark⼀下。
3.1 ⽅案
proguard是最为⼴为使⽤的⼯具之⼀,可是⽤他的客户端⽅式来混淆springboot项⽬的时候最后总得不到可执⾏的jar。后来发现了proguard-maven-plugin这个插件,所有proguard的指令都可以在pom中定义实现,本⽂采⽤proguard-maven-plugin⽅案。
3.2 POM⽂件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId&badagang.data.jpa</groupId>
<artifactId>jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
<name>jpa</name>
<description>JPA project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
&porting.outputEncoding>UTF-8</porting.outputEncoding> <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--MySQL数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- proguard混淆插件-->
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.2.0</version>
<executions>
<execution>
<!-- 打包的时候开始混淆-->
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<injar>${project.build.finalName}.jar</injar>
<!--输出的jar-->
<outjar>${project.build.finalName}.jar</outjar>
<!-- 是否混淆-->
<obfuscate>true</obfuscate>
<options>
<option>-target 1.8</option> <!--指定java版本号-->
<option>-dontshrink</option> <!--默认开启,不做收缩(删除注释、未被引⽤代码)-->
<option>-dontoptimize</option><!--默认是开启的,这⾥关闭字节码级别的优化-->
<option>-adaptclassstrings</option><!--混淆类名之后,对使⽤Class.forName('className')之类的地⽅进⾏相应替代-->
<option>-ignorewarnings
</option><!-- 忽略warn消息,如果提⽰org.apache.http.* 这个包⾥的类有问题,那么就加⼊下述代码:-keep class org.apache.http.** { *; } -dontwarn org.apache.h <option>-keep class org.apache.logging.log4j.util.* { *; }</option>
<option>-dontwarn org.apache.logging.log4j.util.**</option>springboot aop
<option>-keepattributes
Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
</option><!--对异常、注解信息在runtime予以保留,不然影响springboot启动-->
<!--不混淆所有interface接⼝-->
<!-- <option>-keepnames interface **</option>-->
<option>-keepclassmembers enum * { *; }</option><!--保留枚举成员及⽅法-->
<option>-keepparameternames</option>
<option>-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);}
</option> <!--保留main⽅法的类及其⽅法名-->
<!--忽略note消息,如果提⽰javax.annotation有问题,那麽就加⼊以下代码-->
<option>-dontnote javax.annotation.**</option>
<option>-dontnote sun.applet.**</option>
<option>-ls.jar.**</option>
<option>-dontnote org.apachemons.logging.**</option>
<option>-dontnote javax.inject.**</option>
<option>-dontnote org.aopalliance.intercept.**</option>
<option>-dontnote org.aopalliance.aop.**</option>
<option>-dontnote org.apache.logging.log4j.**</option>
<!-- > 以下为需要根据项⽬情况修改 comment by 郭秀志 20200719 > -->
<!--⼊⼝程序类不能混淆,混淆会导致springboot启动不了-->
<option>-keep badagang.data.jpa.JpaApplication</option>
<option>-keep badagang.data.jpa.base.* {*;}</option>
<option>-keep badagang.ity.* {*;}</option>
<option>-keep badagang.del.* {*;}</option>
<option>-keep badagang.ller.* {*;}</option>
<!-- > 以上为需要根据项⽬情况修改 comment by 郭秀志 20200719 > -->
<option>-keep interface * extends * { *; }</option>
<!--不混淆所有类,保存原始定义的注释-->
<option>-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Value *;
}
</option>
</options>
<libs>
<!-- 添加依赖 java8-->
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
</configuration>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论