侦探大挑战
128.12M · 2026-04-22
企业中为了公司的发展,通常会采用分析竞品产品、业务等方式来学习以及弥补自己业务的不足。作为底层的开发人员自认也会去扒竞品公司对应产品的代码,分析亮点以及可取之处,来精进自己的技术以及扩展自己的产品。
通过技术手段通过会使用反编译的方式来解析二进制文件。但是有不少产品使用的代码混淆的技术,大大的提升了逆向工程的难度。
今天,我们就通过**Spring Boot + ProGuard**的实战项目,来给大家好好聊聊Java代码混淆这件事。
代码混淆(Obfuscation)就是把有意义的类名、方法名、变量名改成毫无意义的字母组合,让逆向工程师看得头皮发麻,但又不会影响程序正常运行。
简单来说,就是这样:
public class UserService {
public String getUserPassword(String username) { ... }
}
// 混淆后
public class UserService {
public String a(String b) { ... }
}
**ProGuard**是Java领域最经典的代码混淆工具,主要功能如下:
| 功能 | 说明 |
|---|---|
| 混淆(Obfuscate) | 把类名、方法名、变量名变成a、b、c |
| 优化(Optimize) | 删除无用代码、内联方法、简化逻辑 |
| 压缩(Shrink) | 移除未使用的类和方法,减小JAR体积 |
| 预检(Preverify) | 为Java 6+添加字节码验证信息 |
插件的地址:github.com/wvengen/pro…
本是实战将通过sprinboot+proguard-maven-plugin插件实现代码混淆的逻辑。
java-confusion/
├── pom.xml # Maven配置(含ProGuard插件)
├── proguard.conf # 混淆配置文件
└── src/main/java/com/example/demo/
├── DemoApplication.java # 启动类
├── controller/UserController.java
├── entity/User.java
└── service/UserService.java
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<!-- 打包的時候混淆 -->
<goal>proguard</goal>
</goals>
<configuration>
<obfuscate>true</obfuscate>
<!-- 混淆之前的jar -->
<injar>${project.build.finalName}.jar</injar>
<!-- 混淆之后的jar -->
<outjar>${project.build.finalName}-obfuscated.jar</outjar>
<!-- 混淆时的规则文件 -->
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
<libs>
<!-- ProGuard依赖JDK的核心库 -->
<lib>${java.home}/lib/rt.jar</lib>
</libs>
<!-- 自动生成库配置 --> <generateTemporaryConfigurationFile>true</generateTemporaryConfigurationFile>
</configuration>
</execution>
</executions>
</plugin>
执行命令:
mvn clean package
打包完成后,会生成一个xxxx-obfuscated.jar后缀的混淆包。
核心的配置文件是proguard.conf。
最基础的优化设置
| 配置 | 作用 |
|---|---|
-optimizationpasses 5 | 优化5次,次数越多效果越好,但编译越慢 |
-dontusemixedcaseclassnames | 混淆时不混用大小写,避免Windows文件系统冲突 |
-dontskipnonpubliclibraryclasses | 不跳过非公共库类,全部处理 |
-ignorewarnings | 忽略所有警告,防止打包中断 |
-verbose | 输出详细的混淆过程信息 |
SpringBoot 相关
-keep class org.springframework.** { *; }
️ 重要!Spring大量使用反射和注解,混淆必挂!
不仅是Spring,这些也必须保留:
应用层保留规则
项目里这几个类是核心,必须保留:
# 保留 DemoApplication 类的所有成员不被混淆
# 因为包含 @SpringBootApplication 注解和 main 方法入口
-keep class com.example.demo.DemoApplication { *; }
# 保留 User 实体类的公开字段和方法
# 实体类需要被 JSON 序列化/反序列化,字段名必须保留
-keep public class com.example.demo.entity.User {
public <fields>; # 保留所有公开字段
public <methods>; # 保留所有公开方法
}
# Controller保留方法(路由映射需要)
-keep public class com.example.demo.controller.UserController {
public <methods>;
}
# 此选项将保存接口中的所有原始名称(不混淆)
# Spring 依赖注入需要通过方法名反射调用
-keepnames interface ** { *; }
我们直接打包看看日志:
打包完成之后会生成一些文件:
demo-obfuscation-1.0.0.jar::混淆之前的jar
demo-obfuscation-1.0.0-obfuscated.jar:混淆之后的jar
generated-proguard.conf:依赖的库
proguard_map.txt:是混淆的基本映射
proguard_seed:混淆的原始列表
代码混淆不是银弹,只能加大逆向工程的难度。使用时,应该注意:
觉得有用的话,点个在看转发支持一下,关注我,持续更新更多硬核干货!