xjar 源码流程分析

xjar

xjar是什么

xjar的定义

  1. Spring Boot JAR 安全加密运行工具,同时支持的原生JAR。
  2. 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译
功能特性
  • 无需侵入代码,只需要把编译好的JAR包通过工具加密即可。
  • 完全内存解密,杜绝源码以及字节码泄露或反编译。
  • 支持所有JDK内置加解密算法。
  • 可选择需要加解密的字节码或其他资源文件,避免计算资源浪费。

xjar如何使用

xjar githubd地址:https://github.com/core-lib/xjar

导入依赖
    <dependencies>
        <!--核心库-->
        <dependency>
            <groupId>com.github.core-lib</groupId>
            <artifactId>xjar</artifactId>
            <version>v2.0.6</version>
        </dependency>
        <!--用于读取jar中的文件-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.18</version>
        </dependency>
        <!--资源加载器-->
        <dependency>
            <groupId>com.github.core-lib</groupId>
            <artifactId>loadkit</artifactId>
            <version>v1.0.0</version>
        </dependency>
    </dependencies>
加密普通jar
	public static void main(String[] args) throws Exception {
		String password = args[0];
		XKey xKey = XKit.key(password);
		XJar.encrypt(args[1], args[2], xKey);
		System.out.println("Successfully generated encrypted jar");

	}
解密普通jar
	public static void main(String[] args) throws Exception {
		String password = args[0];
		XKey xKey = XKit.key(password);
		XJar.decrypt(args[1], args[2], xKey);
	}

普通的jar 使用XJar类 进行加密/解密

spring boot 项目使用Xboot 进行加密解密

执行 加密的jar
启动参数说明
参数名称参数含义缺省值说明
–xjar.password密码
–xjar.algorithm密钥算法AES支持JDK所有内置算法,如AES / DES …
–xjar.keysize密钥长度128根据不同的算法选取不同的密钥长度。
–xjar.ivsize向量长度128根据不同的算法选取不同的向量长度。
–xjar.keyfile密钥文件./xjar.key密钥文件相对或绝对路径。

启动后提示输入密码

java -jar /path/to/encrypted.jar

通过传参方式启动

java -jar /path/to/encrypted.jar --xjar.password=PASSWORD

推荐启动方式 nohup 后台启动 指定密钥文件

nohup java -jar /path/to/encrypted.jar --xjar.keyfile=/path/to/xjar.key

密钥文件参数说明
参数名称参数含义缺省值说明
password密码密码字符串
algorithm密钥算法AES支持JDK所有内置算法,如AES / DES …
keysize密钥长度128根据不同的算法选取不同的密钥长度。
ivsize向量长度128根据不同的算法选取不同的向量长度。
hold是否保留false读取后是否保留密钥文件。

xjar原理探究

xjar 加密过程

img

xjar执行过程

img

jar 中的class 是如何解密的

自定义了 XJarClassLoader 继承了 URLClassLoader

其中 XJarClassLoader 自定义了 XJarURLHandler 继承与 URLStreamHandler

XJarURLHandler 用于对url进行处理,其中有个重要属性 indexes

indexes 获取jar 中的 XJAR-INF/INDEXES.IDX

XJarURLConnection 自定义了JarURLConnection 用于 自定义解密加密的类

XJarURLConnection.getInputStream() 获取CipherInputStream

XJarClassLoader.findClass()

->super.findClass(name)出现ClassFormatError->

XJarClassLoader.findResource()->URL.openStream()

->URL.openConnection()->handler.openConnection();

当URL.openConnection() 就会调用 XJarURLHandler.openConnection()

根据class的url是否属于indexes里面的url , 属于就使用XJarURLConnection 进行文件解密

XJarClassLoader.findClass() 如何被触发的
xJarClassLoader = new XJarClassLoader(urlClassLoader.getURLs(), classLoader.getParent(), xLauncher.xDecryptor, xLauncher.xEncryptor, xLauncher.xKey);
 // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }

这里写图片描述

  • 由于 XJarClassLoader 设置的父加载器为 当前classLoader 的父加载器,为ExtClassLoader

  • 基于双亲委派机制,父类加载器不会加载到 当前jar路径下的class ,最后会调用XjarClassLoader的findClass()

  • XjarClassLoader.findClass()会先尝试用URLClassLoader的findClass() 当出现ClassFormatError 则说明当前类可能是加密的, 会尝试使用 自定义的解密方式进行类加载。

ss ,最后会调用XjarClassLoader的findClass()

  • XjarClassLoader.findClass()会先尝试用URLClassLoader的findClass() 当出现ClassFormatError 则说明当前类可能是加密的, 会尝试使用 自定义的解密方式进行类加载。
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值