代码编译安全之classfinal-maven-plugin插件

张春  金牌会员 | 2024-11-3 03:15:35 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 894|帖子 894|积分 2682

ClassFinal-maven-plugin插件是一个用于加密Java字节码的工具
开源地址官网:ClassFinal: Java字节码加密工具 (目前已经暂停维护了)
工作原理

ClassFinal-maven-plugin插件通过调用Java Native
Interface(JNI)实现对Java字节码的加密。具体来说,它会在编译阶段对类文件进行肴杂和加密,然后在运行时动态解密这些类文件。
首先,插件会遍历项目中的全部类文件,并对其进行肴杂处置惩罚。肴杂过程包括重命名类名、方法名、字段名以及改变控制流结构等,目的是使反编译后的代码难以阅读。
接着,插件会对肴杂后的类文件进行加密处置惩罚。加密过程采用了一种名为CFProtect的算法,该算法基于AES加密标准,具有较高的安全性。加密后的类文件存储为二进制格式,不能直接被Java假造机加载。当class被classloader加载时,真正的方法体会被解密注入
。运用的是Java Agent可以去实现字节码插桩、动态跟踪分析。好比skywalking、arms等就是Java Agent技能。
末了,插件会生成一个署理模块(agent module),该模块负责在应用程序启动时加载,并负责解密加密的类文件。署理模块采用JVMTI(Java
Virtual Machine Tool Interface)技能实现,可以在运行时监控和控制Java假造机的举动。
加密结果

1.加密后,方法体被清空,保留方法参数、注解等信息.主要兼容swagger文档注解扫描
2.方法体被清空后,反编译只能看到方法名和注解,看不到方法体的具体内容
3.加密后的项目需要设置javaagent来启动,启动过程中解密class,完全内存解密,不留下任何解密后的文件
4.启动加密后的jar,生成xxx-encrypted.jar,这个就是加密后的jar文件,加密后不可直接实行
5.无暗码启动方式,java-javaagent:xxx-encrypted.jar-jarxxx-encrypted.jar
6.有暗码启动方式,java-javaagent:xxx-encrypted.jar=‘-pwd=暗码’-jarxxx-encrypted.jar __
加密方法

直接增长插件即可,写在Springboot的spring-boot-maven-plugin后面即可,注意修改要加密的packages配置
  1.           <plugin>
  2.                 <!--
  3. 1.加密后,方法体被清空,保留方法参数、注解等信息.主要兼容swagger文档注解扫描  
  4. 2.方法体被清空后,反编译只能看到方法名和注解,看不到方法体的具体内容  
  5. 3.加密后的项目需要设置javaagent来启动,启动过程中解密class,完全内存解密,不留下任何解密后的文件  
  6. 4.启动加密后的jar,生成xxx-encrypted.jar,这个就是加密后的jar文件,加密后不可直接执行  
  7. 5.无密码启动方式,java-javaagent:xxx-encrypted.jar-jarxxx-encrypted.jar  
  8. 6.有密码启动方式,java-javaagent:xxx-encrypted.jar='-pwd=密码'-jarxxx-encrypted.jar  
  9. -->
  10.                 <!-- https://gitee.com/roseboy/classfinal -->
  11.                 <groupId>net.roseboy</groupId>
  12.                 <artifactId>classfinal-maven-plugin</artifactId>
  13.                 <version>1.2.1</version>
  14.                 <configuration>
  15.                     <password>#</password><!--加密打包之后pom.xml会被删除,不用担心在jar包里找到此密码-->
  16. <!--packages配置要加入的包名,会把下面的所有类加密-->
  17.              <packages>com.yulang.proguard.demo.utils,com.yulang.proguard.demo.controller</packages>
  18. <!--                    <cfgfiles>application.properties</cfgfiles>-->
  19.                     <excludes>org.spring</excludes>
  20. <!--                    <libjars>a.jar,b.jar</libjars>-->
  21.                 </configuration>
  22.                 <executions>
  23.                     <execution>
  24.                         <phase>package</phase>
  25.                         <goals>
  26.                             <goal>classFinal</goal>
  27.                         </goals>
  28.                     </execution>
  29.                 </executions>
  30.             </plugin>
复制代码
实践

加密的结果,将全部的方法内容都清空了
![](https://img-
blog.csdnimg.cn/direct/3c4560e71a564680ab59dc138cfc2488.png)![](https://img-
blog.csdnimg.cn/direct/9bf88a4646bb4257adafaeb826b07363.png)
应用启动 方法:
  1. java -javaagent:proguard-demo-1.0-SNAPSHOT-encrypted.jar -jar proguard-demo-1.0-SNAPSHOT-encrypted.jar
复制代码
题目

启动报错
  1. 17:39:11.916 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7b9a4292
  2. 17:39:11.923 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
  3. 17:39:11.949 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
  4. java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
  5.         at org.springframework.util.Assert.notEmpty(Assert.java:470)
  6.         at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations(AutoConfigurationImportSelector.java:180)
  7.         at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:123)
  8.         at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:434)
  9.         at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:879)
  10.         at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809)
  11.         at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:780)
  12.         at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192)
  13.         at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
  14.         at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
  15.         at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
  16.         at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
  17.         at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
  18.         at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
  19.         at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
  20.         at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)
  21.         at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
  22.         at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317)
  23.         at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
  24.         at com.yulang.proguard.demo.ProguardApp.main(ProguardApp.java:19)
  25.         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  26.         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  27.         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  28.         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  29.         at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
  30.         at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
  31.         at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
  32.         at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
复制代码
办理办法,解释掉application的加密和jar包加密就好了
测试

测试启动过程中,除了增长点启动日志,并无什么影响,对于业务日志也没有影响

可以看到日志的行号也不会做任何的变动 ,相比较商用Allatori肴杂,默认会肴杂行号,导致日志排查起来相当困难

缺点

通过dump仍旧能看到源码,但是相对来说,增长了破解的难度
加密解密开销:每次加载类时都需要进行解密利用,这会增长额外的CPU盘算时间。如果加密算法复杂度较高,解密过程大概会成为性能瓶颈。
内存消耗:加密后的类文件大概占用更多存储空间,而且在运行时需要更多的内存来存放解密后的字节码数据。
类加载时间:由于增长了解密环节,类加载的时间会有所增长,特别是在启动阶段或大量类需要加载的时间,大概会感受到明显的耽误。
JIT编译:Java假造机(JVM)通常会对热点代码进行即时(Just-In-
Time,JIT)编译优化以进步实行效率。加密后,JVM大概无法直接辨认并优化这些代码,从而影响实行速度。
目前已经暂停维护了,后期如果存在题目,需要自己修复
扩展

多模块项目,只需要在对应模块配置相应的jar包即可
  1. <libjars>
复制代码
呆板绑定

获取呆板码jar包:classfinal-fatjar-1.2.1.jar
下载地址:<https://repo1.maven.org/maven2/net/roseboy/classfinal-
fatjar/1.2.1/classfinal-fatjar-1.2.1.jar>
呆板绑定只答应加密的项目在特定的呆板上运行;
在需要绑定的呆板上实行以下下令,生成呆板码
java -jar classfinal-fatjar-1.2.1.jar -C
加密时用-code指定呆板码。呆板绑定可同时支持呆板码+暗码的方式加密。

如果拷贝到其他呆板上运行,则会报错

启动加密后的jar

  1. java -javaagent:yourpaoject-encrypted.jar='-pwd 0000000' -jar yourpaoject-encrypted.jar
  2. //参数说明
  3. // -pwd      加密项目的密码  
  4. // -pwdname  环境变量中密码的名字
  5. 插件中配置的密码
  6. <password>#</password><!--加密打包之后pom.xml会被删除,不用担心在jar包里找到此密码-->
复制代码
跋文

其他原理雷同:https://github.com/core-lib/xjar
末了

从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,本领越强机会才越多。
因为入门学习阶段知识点比较杂,所以我讲得比较笼统,大家如果有不懂的地方可以找我咨询,我保证知无不言言无不尽,需要相关资料也可以找我要,我的网盘里一大堆资料都在吃灰呢。
干货主要有:
①1000+CTF历届题库(主流和经典的应该都有了)
②CTF技能文档(最全中文版)
③项目源码(四五十个风趣且经典的练手项目及源码)
④ CTF大赛、web安全、渗透测试方面的视频(适合小白学习)
⑤ 网络安全学习门路图(告别不入流的学习)
⑥ CTF/渗透测试工具镜像文件大全
⑦ 2023暗码学/隐身术/PWN技能手册大全
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表