Securing Spring Boot Production Packages with Code Obfuscation and Encryption Using ClassFinal Maven Plugin
This guide explains how to protect Spring Boot production packages from reverse engineering by applying code obfuscation with ProGuard and full encryption using the ClassFinal Maven plugin, including configuration steps, encrypted startup commands, machine‑binding activation, and the resulting decompilation behavior.
Scenario
Recent project requirements demand deployment to a third‑party server without exposing source code, necessitating security processing of the production startup package to prevent direct decompilation.
Solution
1. Code Obfuscation (ProGuard)
Uses the proguard-maven-plugin . In single‑module projects this is straightforward, but multi‑module projects become complex due to intricate configuration and potential errors when deciding which modules to obfuscate.
2. Code Encryption (ClassFinal)
Adopts the classfinal-maven-plugin , which simplifies protection by configuring a single plugin to encrypt source code, YAML/properties files, and JAR dependencies in the lib directory. It also supports machine‑binding so the encrypted project runs only on specified machines.
ClassFinal project source: https://gitee.com/roseboy/classfinal.git
Project Operation
Add the following plugin configuration to the pom.xml of the startup module, placing it after the spring-boot-maven-plugin to ensure it takes effect.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--
1. After encryption, method bodies are cleared, retaining parameters and annotations (compatible with Swagger).
2. Decompilation shows only method names and annotations.
3. The encrypted JAR requires a javaagent for runtime in‑memory decryption, leaving no decrypted files.
4. The encrypted JAR is named xxx‑encrypted.jar and cannot be executed directly.
5. No‑password start: java -javaagent:xxx‑encrypted.jar -jar xxx‑encrypted.jar
6. Password start: java -javaagent:xxx‑encrypted.jar='-pwd=PASSWORD' -jar xxx‑encrypted.jar
-->
<groupId>net.roseboy</groupId>
<artifactId>classfinal-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<password>#</password>
<excludes>org.spring</excludes>
<packages>${groupId}</packages>
<cfgfiles>application.yml,application-dev.yml</cfgfiles>
<libjars>hutool-all.jar</libjars>
<code>xxxx</code>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classFinal</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>Startup Methods
1. No‑Password Start
java -javaagent:xxx-encrypted.jar -jar xxx-encrypted.jar
2. Password‑Protected Start
java -javaagent:xxx-encrypted.jar='-pwd=密码' -jar xxx-encrypted.jar
Decompilation Effect
After encryption, method bodies are cleared while parameters and annotations remain, ensuring Swagger compatibility.
Decompiled code reveals only method signatures and annotations, not the actual implementation.
During startup, classes are decrypted entirely in memory, leaving no decrypted files on disk.
YAML configuration files appear blank after encryption.
Machine‑Binding Startup
Download the classfinal-fatjar-1.2.1.jar dependency, then run java -jar classfinal-fatjar-1.2.1.jar -C to generate a machine code.
Insert the generated machine code into the plugin's <code> configuration; the packaged project will then run only on that specific machine.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.