xjar 源码流程分析

   日期:2020-07-08     浏览:134    评论:0    
核心提示:xjarxjar是什么xjar的定义Spring Boot JAR 安全加密运行工具,同时支持的原生JAR。基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译功能特性无需侵入代码,只需要把编译好的JAR包通过工具加密即可。完全内存解密,杜绝源码以及字节码泄露或反编译。支持所有JDK内置加解密算法。可选择需要加解密的字节码或其他资源文件,避免计算资源浪费。xjar如何使用xjar githubd地址:htt_xjar 原理

文章目录

  • xjar
    • xjar是什么
      • xjar的定义
        • 功能特性
    • xjar如何使用
        • 导入依赖
        • 加密普通jar
        • 解密普通jar
        • 执行 加密的jar
          • 启动参数说明
          • 密钥文件参数说明
    • xjar原理探究
      • xjar 加密过程
      • xjar执行过程
      • jar 中的class 是如何解密的
        • XJarClassLoader.findClass() 如何被触发的

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 加密过程

xjar执行过程

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 则说明当前类可能是加密的, 会尝试使用 自定义的解密方式进行类加载。
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服