admin 管理员组文章数量: 1184232
一、ClassFinal简介
ClassFinal是一款java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework;可避免源码泄漏或字节码被反编译。
依赖环境:jdk1.8
Gitee: ClassFinal: Java字节码加密工具
1、项目模块说明
- classfinal-core: ClassFinal的核心模块,几乎所有加密的代码都在这里;
- classfinal-fatjar: ClassFinal打包成独立运行的jar包;
- classfinal-maven-plugin: ClassFinal加密的maven插件;
2、功能特性
- 无需修改原项目代码,只要把编译好的jar/war包用本工具加密即可。
- 运行加密项目时,无需求修改tomcat,spring等源代码。
- 支持普通jar包、springboot jar包以及普通java web项目编译的war包。
- 支持spring framework、swagger等需要在启动过程中扫描注解或生成字节码的框架。
- 支持maven插件,添加插件后在打包过程中自动加密。
- 支持加密WEB-INF/lib或BOOT-INF/lib下的依赖jar包。
- 支持绑定机器,项目加密后只能在特定机器运行。
- 支持加密springboot的配置文件。
3、使用场景
项目需要部署,项目用的jdk版本为17,找了一圈,起初想用混淆代码proguard来做,无奈带对17有点兼容性问题,而且虽然代码别混淆但是耐心点debug还是有被利用的可能性,还有一个重要原因,我们项目分成了很多module有很多是相互依赖的,proguard无法对lib进行混淆,而且混淆之后调用上会有一些bug。于是转向使用classfinal解决问题,classfinal可以完美加密源码以及lib依赖,所有的方法在保留主体的前提下清理内容,返回值都为null。并且使用AES加密class内容,解密后的文件在内存中生成比较安全,简单安全谁都爱。
二、使用jar包加密
1、使用jar包来加密打包后的项目
java -jar classfinal-fatjar.jar -file yourpaoject.jar -libjars a.jar,b.jar -packages com.yourpackage,com.yourpackage2 -exclude com.yourpackage.Main -pwd 123456 -Y
2、使用jar来加密的一些基本参数
参数说明 -file 加密的jar/war完整路径 -packages 加密的包名(可为空,多个用","分割) -libjars jar/war包lib下要加密jar文件名(可为空,多个用","分割) -cfgfiles 需要加密的配置文件,一般是classes目录下的yml或properties文件(可为空,多个用","分割) -exclude 排除的类名(可为空,多个用","分割) -classpath 外部依赖的jar目录,例如/tomcat/lib(可为空,多个用","分割) -pwd 加密密码,如果是#号,则使用无密码模式加密 -code 机器码,在绑定的机器生成,加密后只可在此机器上运行 -Y 无需确认,不加此参数会提示确认以上信息
执行完之后会在当前路径下生成一个后缀带了-encrypt.jar的文件,这个就是源代码加密后生成的jar包。记得给别人就给加密后的包。
运行的时候要使用javaagent来运行,因为他要把你加密的包解密之后才能跑。
三、使用maven插件加密
1、引入maven插件并且配置
这里的maven插件建议写在最终打包的那个项目中去,如果有很多依赖,那就把这些依赖的jar包找出来写到配置里面去做加密。
<!-- ClassFinal加密 -->
<plugin>
<groupId>net.roseboy</groupId>
<artifactId>classfinal-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<!-- 可采用机器码的方式绑定机器 需要提前获得机器码写入code -->
<!--<code></code> -->
<!-- 密码为#可以直接用javaagent启动 也可以设置其他密码 dockerFile脚本中需要标注=“-pwd 123456” -->
<password>123456</password>
<!-- 所需要加密的包路径 -->
<packages>com.xxx.123</packages>
<excludes>org.spring</excludes>
<!-- 所需要加密配置文件 -->
<cfgfiles>
<!-- application.yml, -->
<!-- application-dev.yml, -->
<!-- application-prod.yml -->
</cfgfiles>
<!--要进行加密的依赖jar包 -->
<libjars>
cecomm-api-alarm-1.0.0-SNAPSHOT.jar,
cecomm-api-comm-1.0.0-SNAPSHOT.jar,
cecomm-api-data-processor-1.0.0-SNAPSHOT.jar,
cecomm-api-device-1.0.0-SNAPSHOT.jar,
cecomm-api-gui-1.0.0-SNAPSHOT.jar,
cecomm-api-subsys-1.0.0-SNAPSHOT.jar,
cecomm-api-sys-1.0.0-SNAPSHOT.jar
</libjars>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>classFinal</goal>
</goals>
</execution>
</executions>
</plugin>
配置写完后再执行maven中package就可以再target目录下看到加密后的包了。
2、无密码启动
注意:无密码启动模式并不太安全,因为classfinal加密后jar包下生成一个名为org.springframework,config.pass的文件,这个里面装的就是随机生成的32位明文,这个密码进行md5加密后保存密文,下一次无密码启动的时候就去拿明文进行md5校验,因此不建议用无密码启动这种方式不太安全。
3、有密码启动
在pom中设置好密码打包后执行,注意启动的时候加上启动参数 -pwd (密码)来启动jar包
java -javaagent xxx.jar="-pwd 123456" -jar xxx.jar
如果不指定的话执行的时候会弹窗手输密码进去:
4、机器码绑定
点此处classfinal-fatjar-1.2.1.jar下载
java -jar classfinal-fatjar-1.2.1.jar -C
机器码利用这里classfinal给的jar包,到指定的机器上去执行,得到长串机器码,以code标签的方式写到配置文件中,这样jar包就只能在指定的机器上启动了,注意机器码和本身设置的密码可同时不影响使用。
5、密码文件启动
同样在pom里面配配置好启动密码,并且将明文密码写在classfinal.txt里面,并且将txt文件与加密后的jar包放在同一个文件夹中,启动的时候不需要添加任何参数直接执行,程序运行后在删除密码文件下次就执行失败了。
java -javaagent:xxx.jar -jar xxx.jar
也可以在程序中通过命令行参数让他执行成功后删除源文件中的明文。但是程序有个bug需要修改下,这个自行根据需要来完成,路径为:classfinal-core中的CoreAgent.java
public static char[] readPasswordFromFile(CmdLineOption options) {
String path = JarUtils.getRootPath(null);
if (!path.endsWith(".jar")) {
return null;
}
String jarName = path.substring(path.lastIndexOf("/") + 1);
path = path.substring(0, path.lastIndexOf("/") + 1);
String configName = jarName.substring(0, jarName.length() - 3) + "classfinal.txt";
File config = new File(path, configName);
if (!config.exists()) {
config = new File(path, "classfinal.txt");
}
String args = null;
char[] pwd;
if (config.exists()) {
args = IoUtils.readTxtFile(config);
}
if (StrUtils.isEmpty(args)) {
return null;
}
//不包含空格文件存的就是密码
if (!args.contains(" ")) {
pwd = args.trim().toCharArray();
}else {
options.parse(args.trim().split(" "));
pwd = options.getOptionValue("pwd", "").toCharArray();
Const.DEBUG = options.hasOption("debug");
}
//删除文件中的密码
if (!"false".equalsIgnoreCase(options.getOptionValue("del"))
&& !"no".equalsIgnoreCase(options.getOptionValue("del"))) {
args = "";
IoUtils.writeTxtFile(config, args);
}
return pwd;
}
6、tomcat下运行加密的war
将加密后的war放在tomcat/webapps下, tomcat/bin/catalina 增加以下配置:
//linux下 catalina.sh
CATALINA_OPTS="$CATALINA_OPTS -javaagent:classfinal-fatjar.jar='-pwd 0000000'";
export CATALINA_OPTS;
//win下catalina.bat
set JAVA_OPTS="-javaagent:classfinal-fatjar.jar='-pwd 000000'"
//参数说明
// -pwd 加密项目的密码
// -nopwd 无密码加密时启动加上此参数,跳过输密码过程
// -pwdname 环境变量中密码的名字
四、使用dockerFile部署加密后的包
使用dockerFile来部署加密后的项目,配置如下:
ADD ./target/cloud-admin-encrypted.jar ./app.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:./app.jar='-pwd 123456'"
或者
ENV JAVA_TOOL_OPTIONS="-javaagent:./app.jar"
ENTRYPOINT ["java", "-jar", "app.jar"]
本文标签: 项目 ClassFinal
版权声明:本文标题:使用ClassFinal加密项目 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1763719029a3264083.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论