• Java class 文件安全加密工具对比与ClassFinal实战


    前言

    相信不少的同学开发的软件都是用户商业化,对于这些商业运营的项目很多都会直接部署在客户方,这样就可能会导致项目源码泄露。当然,作为Java语言的搬砖人打的jar包更是如此,可以直接通过GUI反编译轻而易举拿到源码。那么,有没有对我们class文件加密和代码混淆的实战方案呢?答案当然是有的,今天我们就分享一下常规的加密方案。

    常见加密方案对比

    XJar

    Spring Boot JAR 安全加密运行工具,同时支持的原生JAR。
    基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译

    功能特性:
    无需侵入代码,只需要把编译好的JAR包通过工具加密即可。
    完全内存解密,杜绝源码以及字节码泄露或反编译。
    支持所有JDK内置加解密算法。
    可选择需要加解密的字节码或其他资源文件,避免计算资源浪费。

    运行环境:
    新版XJar只支持go启动器模式启动加密后的jar包 , 加密后需要go环境生成go启动器 . 运行时不需要go环境。

    加密原理:
    对jar的字节码加密 , 启动jar包时调用自定义的类加载器, 重写findClass方法,拿到字节流后,先解密再调Classloader的defineClass方法,初始化成Class对象。

    加密结果:
    加密后的Class不能反编译。
    在这里插入图片描述

    ProGuard

    ProGuard 是一个免费的 Java 类文件的压缩,优化,混淆器。它删除没有用的类,字段,方法与属性。使字节码最大程度地优化,使用简短且无意义的名字来重命名类、字段和方法 。

    功能特性:
    1、压缩(shrink) 移除未使用的类、方法、字段等;
    2、优化(optimize)优化字节码、简化代码等操作;
    3、混淆(obfuscate)使用简短的、无意义的名称重全名类名、方法名、字段等;
    4、预校验(preverify)为class添加预校验信息。

    运行环境:
    jdk,不需要额外运行环境。

    加密结果:
    混淆后的class反编译后都是一些魔法命名字符,增加阅读难度。
    在这里插入图片描述

    ClassFinal

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

    项目模块说明:
    1、classfinal-core: ClassFinalde 的核心模块,几乎所有加密的代码都在这里;
    2、classfinal-fatjar: ClassFinal 打包成独立运行的 jar 包;
    3、classfinal-maven-plugin: ClassFinal 加密的 maven 插件;

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

    环境依赖:
    JDK 1.8 +

    本工具使用 AES 算法加密 class 文件,密码是保证不被破解的关键,请保存好密码,请勿泄漏。
    密码一旦忘记,项目不可启动且无法恢复,请牢记密码。
    本工具加密后,原始的 class 文件并不会完全被加密,只是方法体被清空,保留方法参数、注解等信息,这是为了兼容 spring,swagger 等扫描注解的框架; 方法体被清空后,反编译者只能看到方法名和注解,看不到方法的具体内容;当 class 被 classloader 加载时,真正的方法体会被解密注入。

    加密结果:
    配置文件反编译后为空
    在这里插入图片描述

    class文件反编译后直接隐藏方法体
    在这里插入图片描述

    ClassFinal实战

    由于我们不希望引入其他外部依赖环境,遂选择ClassFinal进行代码混淆,可以达到隐藏配置文件内容和清空方法体的效果,即使外部人员拿到源码也不能仿造系统。

    纯命令方式

    下载工具

    https://repo1.maven.org/maven2/net/roseboy/classfinal-fatjar/1.2.1/classfinal-fatjar-1.2.1.jar

    参数说明

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

    执行以下命令

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

    结果: 生成 yourpaoject-encrypted.jar,这个就是加密后的jar文件;加密后的文件不可直接执行,需要配置javaagent。
    在这里插入图片描述

    执行jar

    java -javaagent:yourpaoject-encrypted.jar='-pwd 123456' -jar yourpaoject-encrypted.jar
    
    • 1

    maven插件方式

    引入ClassFinal插件后直接package即可生成加密包

    pom引入插件

    
        net.roseboy
        classfinal-maven-plugin
        1.2.1
        
            #
            yourpackage
            org.spring
            yourconfig
            yourjar
        
        
            
                package
                
                    classFinal
                
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    mvn打包

    mvn package -Dmaven.test.skip=true
    
    • 1

    在这里插入图片描述

    反编译jar

    配置文件全部清空
    在这里插入图片描述

    class文件方法体全部清空
    在这里插入图片描述

    依赖的lib包方法体全部清空
    在这里插入图片描述

    写在最后

    非常重要的项目推荐使用XJar可以完全隐藏Class文件内容,但是需要额外的go环境支持,也可以保守选择ClassFinal直接无侵入达到隐藏方法体和配置文件内容的目的。当然任何的加密和代码混淆的方案都只是增加反编译破解难度,在实际的生产中还需要增加远程鉴权、机器码植入验证、远程依赖加载等等方式保证软件的控制权。

  • 相关阅读:
    达摩院年终预测出炉:2022 十大科技趋势,AI for Science 高居榜首
    vector接口介绍&迭代器失效问题
    分布式事务最终一致性的简单案例
    643. 子数组最大平均数I(滑动窗口)
    码蹄集 - MT3114 · 有趣的平衡 - 用样例通俗地讲解
    java.lang.Float类下toString()方法具有什么功能呢?
    面试字节跳动测试岗被吊打,60天苦修这些笔记,侥幸收获offer
    Python制作经典坦克大战小游戏
    An动画优化之补间形状与传统补间的优化
    网络流量安全分析-工作组异常
  • 原文地址:https://blog.csdn.net/weixin_39970883/article/details/132848152