为了防止源码被泄露,一般要对代码进行混淆或者加密,尝试了几种混淆方案,对于部分代码可以混淆,但是对数据结构、数据库操作、映射文件等数据无法混淆,导致大部分代码还是暴露在可以被直接获取的层面。后来找到一个开源工具XJar,可以直接对JAR包进行加密。
加密方案
XJar
XJar是Spring Boot JAR 安全加密运行工具,同时支持的原生JAR。
基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译。
XJar的使用
获取xjar.jar
在IDE中导入XJar工程,由于默认maven配置打包不包含依赖包,会导致生成的Xjar.jar在加密工程中不生效。
于是做了如下修改:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>util.Microseer</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
最终打包出来包含有依赖jar包xjar-v1.1.0-jar-with-dependencies.jar
编写加解密工程
工程引入xjar-v1.1.0-jar-with-dependencies.jar
并新建main方法
package com.c;
import io.xjar.boot.XBoot;
import java.io.File;
/**
* 代码描述
*
* @author c 2019/1/7
*/
public class Application {
// Spring-Boot Jar包加密
public static void main(String[] args) throws Exception {
// 加密密钥
String password = "yourpassword";
File plaintext = new File("C:\\Users\\xxx\\platform-exec.jar");
File encrypted = new File("C:\\Users\\xxx\\platform.jar");
XBoot.encrypt(plaintext, encrypted, password);
}
// // Spring-Boot Jar包解密
// public static void main(String[] args) throws Exception {
// String password = "yourpassword";
// File encrypted = new File("C:\\Users\\xxx\\platform.jar");
// File decrypted = new File("C:\\Users\\xxx\\platform-temp.jar");
// XBoot.decrypt(encrypted, decrypted, password);
// }
}
则得到加密后的platform.jar包
运行加密后的包
通过java -jar platform.jar运行jar包的时候发现,需要输入密码,但是这样交付的时候其实把密码已经泄露了,用解密方法一解密,源码依旧会被看到。
搜索关键字password:
获取到io.xjar.boot.XBootLauncher的public XBootLauncher(String… args)方法中有如下代码
if (password == null) {
Console console = System.console();
char[] chars = console.readPassword("password:");
password = new String(chars);
}
这里是获取了用户输入的密码,然后写入password变量中再做后续动作,将该代码修改为
if (password == null) {
password = "yourpassword";
}
同时io.xjar.jar.XJarLauncher的public XJarLauncher(String… args)方法中也有上述代码,同样的进行修改
则在运行的时候,不会再提示输入password。