前言
如果项目要求部署到其他公司的服务器上,但是又不想将源码泄露出去。要求对正式环境的启动包进行安全性处理,防止客户直接通过反编译工具将代码反编译出来。
方案解决:
第一种方案使用代码混淆
采用 proguard-maven-plugin 插件
在单模块中此方案还算简单,但是现在项目一般都是多模块,一个模块依赖多个公共模块。那么使用此方案就比较麻烦,配置复杂,文档难懂,各模块之间的调用在是否混淆时极其容易出错。
第二种方案使用代码加密
采用classfinal-maven-plugin插件
此方案比对上面的方案来说,就简单了许多。直接配置一个插件就可以实现源码的安全性保护。并且可以对yml、properties配置文件以及lib目录下的maven依赖进行加密处理。若想指定机器启动,支持绑定机器,项目加密后只能在特定机器运行。
ClassFinal 项目源码地址:https://gitee.com/roseboy/classfinal
这里介绍的是第二种方案
第一步:在 pom.xml 中添加插件配置
java
在 <build><plugins> 节点下添加以下配置(无需修改项目源代码)
<plugin>
<!--
1. 加密后,方法体被清空,保留方法参数、注解等信息.主要兼容swagger文档注解扫描
2. 方法体被清空后,反编译只能看到方法名和注解,看不到方法体的具体内容
3. 加密后的项目需要设置javaagent来启动,启动过程中解密class,完全内存解密,不留下任何解密后的文件
4. 启动加密后的jar,生成xxx-encrypted.jar,这个就是加密后的jar文件,加密后不可直接执行
5. 无密码启动方式,java -javaagent:xxx-encrypted.jar -jar xxx-encrypted.jar
6. 有密码启动方式,java -javaagent:xxx-encrypted.jar='-pwd= 密码' -jar xxx-encrypted.jar
-->
<groupId>net.roseboy</groupId>
<artifactId>classfinal-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<!-- 加密密码,# 表示无密码模式 -->
<password>#</password>
<!-- 需要加密的包名(多个用逗号分隔) -->
<packages>com.yourcompany.yourproject</packages>
<!-- 需要加密的配置文件(支持通配符) -->
<cfgfiles>application.yml,application-*.yml</cfgfiles>
<!-- 需要加密的依赖 jar(如:lib/fastjson-1.2.83.jar) -->
<libjars></libjars>
<!-- 机器绑定码(留空则不绑定机器) -->
<code></code>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classFinal</goal>
</goals>
</execution>
</executions>
</plugin>
关键参数说明:
<password>:启动密码,#表示无密码模式;若设密码,启动时需通过-pwd参数提供
<packages>:指定要加密的包路径(如com.yourcompany),空值会加密所有类
<cfgfiles>:加密配置文件内容,反编译后显示为空文件
<libjars>:加密 BOOT-INF/lib 下的特定依赖 jar 包
<code>:机器码,实现"一机一码"绑定
第二步:执行 Maven 打包
mvn clean package
执行过程 :Maven 会先编译项目,然后在
package阶段自动触发 classfinal 加密,最终在target/目录生成两个文件:
your-project-1.0.jar:原始未加密包(可删除)
your-project-1.0-encrypted.jar:加密后的部署包
第三步:生成机器码
如需绑定到特定服务器,先获取机器码:
下载 classfinal-fatjar-1.2.1.jar 工具
在目标服务器上执行:
java -jar classfinal-fatjar-1.2.1.jar -C
将生成的机器码填入 pom.xml 的
<code>标签中,重新打包
第四步:部署与启动
加密后的 JAR 包不能直接运行 ,必须使用 -javaagent 参数启动:
无密码模式:
java -javaagent:your-project-1.0-encrypted.jar -jar your-project-1.0-encrypted.jar
有密码模式 (假设密码为 123456):
java -javaagent:your-project-1.0-encrypted.jar='-pwd 123456' -jar your-project-1.0-encrypted.jar
第五步:验证加密效果
使用 JD-GUI 或其他反编译工具打开加密后的 JAR 包,预期结果:
-
配置文件 (如
application.yml)内容为空 -
class 文件的方法体被清空,仅保留方法签名和注解
-
依赖 jar 同样被加密,无法查看源码