当前位置: 首页 > news >正文

深度揭秘!Java Class 文件加密终极指南,有效保护你的核心代码

前言

在某次聚餐中,朋友聊起他接了一个私单,他不想把他的核心代码开放出去,但又想项目能正常运行。翻译成技术术语就是他想对源码进行混淆或者加密。之前我写过一篇文章聊聊如何进行代码混淆。今天我们来聊另一个的话题,聊聊如何利用ClassFinal对代码进行加密。

ClassFinal

ClassFinal简介

ClassFinal是一款java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework;可避免源码泄漏或字节码被反编译。

gitee地址:https://gitee.com/roseboy/classfinal

功能特性

  • 无需修改原项目代码,只要把编译好的jar/war包用本工具加密即可。
  • 运行加密项目时,无需求修改tomcat,spring等源代码。
  • 支持普通jar包、springboot jar包以及普通java web项目编译的war包。
  • 支持spring framework、swagger等需要在启动过程中扫描注解或生成字节码的框架。
  • 支持maven插件,添加插件后在打包过程中自动加密。
  • 支持加密WEB-INF/lib或BOOT-INF/lib下的依赖jar包。
  • 支持绑定机器,项目加密后只能在特定机器运行。
  • 支持加密springboot的配置文件。

项目模块说明

  • classfinal-core: ClassFinal的核心模块,几乎所有加密的代码都在这里;
  • classfinal-fatjar: ClassFinal打包成独立运行的jar包;
  • classfinal-maven-plugin: ClassFinal加密的maven插件;

如何使用

1、加密

方法一 使用classfinal-fatjar.jar

执行如下命令

java -jar classfinal-fatjar.jar -file yourproject.jar -libjars a.jar,b.jar -packages com.yourpackage,com.yourpackage2 -exclude com.yourpackage.Main -pwd 123456 -Y

参数说明

-file        加密的jar/war完整路径
-packages    加密的包名(可为空,多个用","分割)
-libjars     jar/war包lib下要加密jar文件名(可为空,多个用","分割)
-cfgfiles    需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割)
-exclude     排除的类名(可为空,多个用","分割)
-classpath   外部依赖的jar目录,例如/tomcat/lib(可为空,多个用","分割)
-pwd         加密密码,如果是#号,则使用无密码模式加密
-code        机器码,在绑定的机器生成,加密后只可在此机器上运行
-Y           无需确认,不加此参数会提示确认以上信息

方法二: 使用classfinal-maven-plugin插件

在项目pom配置classfinal-maven-plugin插件

 <plugin><groupId>net.roseboy</groupId><artifactId>classfinal-maven-plugin</artifactId><version>1.2.1</version><configuration><password>123456</password>               <!--加密密码,如果是#号,则使用无密码模式加密--><packages>*</packages>                              <!--加密的包名(可为空,多个用","分割)--><cfgfiles>*.yml</cfgfiles>                          <!--需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割)--><!--<libjars>oneclickedcrypt-1.0-SNAPSHOT.jar</libjars>--> <!--jar/war包lib下要加密jar文件名(可为空,多个用","分割)--><!--<cfgpasspath>/etc/.env</cfgpasspath>-->         <!--密码文件路径,可为空,默认 /etc/.env--><!--<excludes>com.Test</excludes>-->                <!--排除不需要加密的文件--><!--<classpath></classpath>-->                      <!--外部依赖jarlib--><!-- <debug>true</debug>    -->                    <!--调试模式,打印debug日志--></configuration><executions><execution><phase>package</phase><goals><goal>classFinal</goal></goals></execution></executions></plugin>

运行mvn package时会在target下自动加密生成yourproject-encrypted.jar,maven插件的参数名称与直接运行的参数相同

注: 加密时-pwd参数设为#,启动时可不用输入密码; 如果是war包,启动时指定参数 -nopwd,跳过输密码过程。

加密后的效果示例

加密前:

@RestController
@RequestMapping("user")
@RequiredArgsConstructor
@Slf4j
public class UserController {private final UserService userService;@GetMapping("list")public List<User> list(){return userService.list();}}

加密后:

@RestController
@RequestMapping("user")
@RequiredArgsConstructor
@Slf4j
public class UserController {private static final Logger log = LoggerFactory.getLogger(UserController.class);private final UserService userService;@GetMapping({"list"})public List<User> list() {return null;}}

加密前: yml文件内容


加密后: yml文件内容


加密后,yml文件内容会被清空

2、启动加密后的jar

加密后的项目需要设置javaagent来启动,项目在启动过程中解密class,完全内存解密,不留下任何解密后的文件。

解密功能已经自动加入到 yourproject-encrypted.jar中,所以启动时-javaagent与-jar相同,不需要额外的jar包。

启动jar项目执行以下命令:

java -javaagent:yourproject-encrypted.jar='-pwd 123456' -jar yourproject-encrypted.jar//参数说明
// -pwd      加密项目的密码  
// -pwdname  环境变量中密码的名字

注: 该工具使用AES算法加密class文件,密码是保证不被破解的关键,请保存好密码,请勿泄漏。

密码一旦忘记,项目不可启动且无法恢复,请牢记密码。

该工具加密后,原始的class文件并不会完全被加密,只是方法体被清空,保留方法参数、注解等信息,这是为了兼容spring,swagger等扫描注解的框架; 方法体被清空后,反编译者只能看到方法名和注解,看不到方法的具体内容;当class被classloader加载时,真正的方法体会被解密注入。

为了保证项目在运行时的安全,启动jvm时请加参数: -XX:+DisableAttachMechanism 。

总结

本文介绍了如何利用ClassFinal对代码进行加密。这个工具类在使用上可以说非常简单,不过有点可惜,这个项目目前已经不再维护,有其他网友基于ClassFinal进行改造,开源了class-winter,感兴趣的朋友可以查看如下网址https://gitee.com/JustryDeng/class-winter

demo链接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-encrypt

http://www.sczhlp.com/news/933.html

相关文章:

  • springboot项目打包成docker镜像
  • 克劳德代码与 Cursor 的问题:AI 编程的死亡螺旋
  • [题解]P5094 [USACO04OPEN] MooFest G 加强版
  • Win10专业版如何关闭Windows错误报告的问题
  • Win11正式版玩游戏输入法冲突的问题
  • Elasticsearch Circuit Breaker 全面解析与最佳实践 - 教程
  • ROS1(20.04 noetic) + PX4 + AirSim
  • 扩散模型-PPDM-95 - jack
  • 5.5 减少过程调用
  • spring springmvc springboot的区别
  • 13N90-ASEMI太阳能逆变器专用13N90
  • 基于Matlab的无人机地面固定目标稳定跟踪
  • 在Go语言微服务中实现服务监控
  • readv() writev()
  • Spring 中的 BeanFactory 和 ApplicationContext
  • Umi 约定式路由解析
  • SFUD库应用教程:串行SPI Flash驱动开发的最佳实践
  • 【刷题笔记】Peaks
  • spring security
  • required关键字和特性的区别
  • 详细介绍:理想不再“追星”华为。
  • C++小白修仙记_LeetCode刷题_1.两数之和
  • synchronized底层实现是什么 lock底层是什么 有什么区别
  • iOS 性能监控 苹果手机后台运行与能耗采样实战指南
  • pygame小游戏打飞机_1展示窗口
  • 个人版Navicat17 Lite版本安装教程(附安装包)2025最新版详细图文安装教程
  • Fluent许可状态监控工具
  • 链上充值监听与自动划转资金流程实现 - fox
  • 如何缓解Petya和WannaCrypt等快速网络攻击 | MSRC博客
  • 基于Amazon Translate的深度学习教材自动翻译系统