赞
踩
ClassFinal是一款java class文件安全加密工具,支持直接加密jar包或war包,无需修改任何项目代码,兼容spring-framework;可避免源码泄漏或字节码被反编译。
Gitee : ClassFinal: Java字节码加密工具
接到一项任务,由于涉及知识产权保护,需要对关键代码片段进行加密处理(核心库)。因此,我选择了ClassFinal工具来实现字节码层面的加密。
- <plugin>
- <!-- https://gitee.com/roseboy/classfinal -->
- <groupId>net.roseboy</groupId>
- <artifactId>classfinal-maven-plugin</artifactId>
- <version>1.2.1</version>
- <configuration>
- <password>000000</password><!--加密打包之后pom.xml会被删除,不用担心在jar包里找到此密码-->
- <packages>com.yourpackage,com.yourpackage2</packages>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>classFinal</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-javaagent:yourproject-encrypted.jar="-pwd 000000"
IDEA中启动运行一切正常,打包成jar包启动后运行到核心包代码块解密失败,代码无法正常执行?
Spring FatJar使用了LaunchedURLClassLoader去加载FatJar中的class和jar嵌套的jar(即jar in jar),显然按照这个逻辑核心包代码块也交由LaunchedURLClassLoader去加载。但是我们使用了javaagent:yourproject-encrypted.jar去执行字节码解密,而代理包中的class是默认交由AppClassloader去加载的,Classfinal默认生成的代理包又包含了所有的核心包代码块(只需用到Classfinal解密代码),这就导致了问题的出现。因为LaunchedURLClassLoader是AppClassLoader的子类加载器,当核心包里面的类调用到被LaunchedURLClassLoader加载的类时会报ClassNoFound。
举个例子:
一、核心库代码String2DateConvert
- public class String2DateConvert implements Converter<String, Date> {
- @Override
- public Date convert(String s) {
- if (StringUtils.isNotBlank(s)) {
- DateFormat dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- try {
- return dtf.parse(s);
- } catch (ParseException e) {
- log.error("日期格式转换失败; {}", e.getMessage());
- }
- }
- return null;
- }
- }
二、spring boot项目引用核心包代码
- public void test() {
- String2DateConvert string2DateConvert = new String2DateConvert();
- string2DateConvert.convert("2023-01-01");
- }
三、其中核心库引用的StringUtils来自apache.commons.lang3包,该第三方包是交由外部LaunchedURLClassLoader。根据双亲委派机制,是无法从AppClassLoader拿到LaunchedURLClassLoader加载的类,因此会报:org.apache.commons.lang.StringUtils NoClassDefFoundError
其实就是将代理包中的非解密代码删除掉
源码修改如下:先打包核心包,再打包代理包
预告:如何支持多重jar包解密,即spring boot包也进行一层加密?Classfinal问题处理及改造升级(二)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。