diff --git a/pom.xml b/pom.xml
index dac3df3..054f07c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.xjar
xjar
- v2.0.5
+ v3.0.0-demo-build-3
xjar
@@ -40,6 +40,18 @@
2.0.1.RELEASE
provided
+
+ com.ibeetl
+ beetl
+ 3.0.8.RELEASE
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
diff --git a/src/main/java/io/xjar/XArchiveDecryptor.java b/src/main/java/io/xjar/XArchiveDecryptor.java
new file mode 100644
index 0000000..529c5f7
--- /dev/null
+++ b/src/main/java/io/xjar/XArchiveDecryptor.java
@@ -0,0 +1,39 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * 记录可过滤的加密器
+ *
+ * @author Payne 646742615@qq.com
+ * 2018/11/23 20:38
+ */
+public abstract class XArchiveDecryptor extends XEntryDecryptor implements XDecryptor, XEntryFilter {
+
+ protected XArchiveDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
+ super(xDecryptor, filter);
+ }
+
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ decrypt(key, new File(src), new File(dest));
+ }
+
+ @Override
+ public void decrypt(XKey key, File src, File dest) throws IOException {
+ try (
+ FileInputStream fis = new FileInputStream(src);
+ FileOutputStream fos = new FileOutputStream(dest)
+ ) {
+ decrypt(key, fis, fos);
+ }
+ }
+
+ protected static abstract class XArchiveDecryptorBuilder, B extends XArchiveDecryptorBuilder> extends XEntryDecryptorBuilder {
+ }
+}
diff --git a/src/main/java/io/xjar/XArchiveEncryptor.java b/src/main/java/io/xjar/XArchiveEncryptor.java
new file mode 100644
index 0000000..b72503c
--- /dev/null
+++ b/src/main/java/io/xjar/XArchiveEncryptor.java
@@ -0,0 +1,39 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * 记录可过滤的加密器
+ *
+ * @author Payne 646742615@qq.com
+ * 2018/11/23 20:38
+ */
+public abstract class XArchiveEncryptor extends XEntryEncryptor implements XEncryptor, XEntryFilter {
+
+ protected XArchiveEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
+ super(xEncryptor, filter);
+ }
+
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ encrypt(key, new File(src), new File(dest));
+ }
+
+ @Override
+ public void encrypt(XKey key, File src, File dest) throws IOException {
+ try (
+ FileInputStream fis = new FileInputStream(src);
+ FileOutputStream fos = new FileOutputStream(dest)
+ ) {
+ encrypt(key, fis, fos);
+ }
+ }
+
+ protected static abstract class XArchiveEncryptorBuilder, B extends XArchiveEncryptorBuilder> extends XEntryEncryptorBuilder {
+ }
+}
diff --git a/src/main/java/io/xjar/XCompiler.java b/src/main/java/io/xjar/XCompiler.java
new file mode 100644
index 0000000..ccc0181
--- /dev/null
+++ b/src/main/java/io/xjar/XCompiler.java
@@ -0,0 +1,26 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * 编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/15 10:33
+ */
+public interface XCompiler {
+
+ /**
+ * 编译
+ *
+ * @param xKey 密钥
+ * @param xSignature 签名
+ * @return 编译后文件
+ * @throws IOException I/O异常
+ */
+ File compile(XKey xKey, XSignature xSignature) throws IOException;
+
+}
diff --git a/src/main/java/io/xjar/XConstants.java b/src/main/java/io/xjar/XConstants.java
index 349f756..8e73027 100644
--- a/src/main/java/io/xjar/XConstants.java
+++ b/src/main/java/io/xjar/XConstants.java
@@ -10,9 +10,6 @@ public interface XConstants {
String BOOT_INF_CLASSES = "BOOT-INF/classes/";
String BOOT_INF_LIB = "BOOT-INF/lib/";
- String WEB_INF_CLASSES = "WEB-INF/classes/";
- String WEB_INF_LIB = "WEB-INF/lib/";
-
String META_INF_MANIFEST = "META-INF/MANIFEST.MF";
String XJAR_SRC_DIR = XConstants.class.getPackage().getName().replace('.', '/') + "/";
String XJAR_INF_DIR = "XJAR-INF/";
@@ -40,11 +37,4 @@ public interface XConstants {
int DEFAULT_KEYSIZE = 128;
int DEFAULT_IVSIZE = 128;
- // 保留密钥在 META-INF/MANIFEST.MF 中,启动时无需输入密钥。
- int FLAG_DANGER = 1;
- // 危险模式:保留密钥
- int MODE_DANGER = FLAG_DANGER;
- // 普通模式
- int MODE_NORMAL = 0;
-
}
diff --git a/src/main/java/io/xjar/XDecryptor.java b/src/main/java/io/xjar/XDecryptor.java
index 256d685..5f859dc 100644
--- a/src/main/java/io/xjar/XDecryptor.java
+++ b/src/main/java/io/xjar/XDecryptor.java
@@ -15,6 +15,16 @@
*/
public interface XDecryptor {
+ /**
+ * 解密,将目标文件解密输出至目标文件。
+ *
+ * @param key 密钥
+ * @param src 源文件
+ * @param dest 目标文件
+ * @throws IOException I/O 异常
+ */
+ void decrypt(XKey key, String src, String dest) throws IOException;
+
/**
* 解密,将目标文件解密输出至目标文件。
*
diff --git a/src/main/java/io/xjar/XDigest.java b/src/main/java/io/xjar/XDigest.java
new file mode 100644
index 0000000..4e9ebb5
--- /dev/null
+++ b/src/main/java/io/xjar/XDigest.java
@@ -0,0 +1,32 @@
+package io.xjar;
+
+/**
+ * 摘要算法
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/3 22:25
+ */
+public interface XDigest {
+
+ /**
+ * 计算数据摘要
+ *
+ * @param buf 缓冲
+ * @param off 下标
+ * @param len 长度
+ */
+ void digest(byte[] buf, int off, int len);
+
+ /**
+ * 结束计算并返回摘要值
+ *
+ * @return 最终摘要值
+ */
+ byte[] finish();
+
+ /**
+ * 恢复初始状态
+ */
+ void resume();
+
+}
diff --git a/src/main/java/io/xjar/XDigestFactory.java b/src/main/java/io/xjar/XDigestFactory.java
new file mode 100644
index 0000000..e028e17
--- /dev/null
+++ b/src/main/java/io/xjar/XDigestFactory.java
@@ -0,0 +1,30 @@
+package io.xjar;
+
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 摘要算法对象工厂
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/5 10:16
+ */
+public interface XDigestFactory {
+
+ /**
+ * 生产摘要算法对象
+ *
+ * @param algorithm 摘要算法
+ * @return 摘要算法对象
+ * @throws NoSuchAlgorithmException 摘要算法不支持
+ */
+ XDigest acquire(String algorithm) throws NoSuchAlgorithmException;
+
+ /**
+ * 回收摘要算法对象
+ *
+ * @param algorithm 摘要算法
+ * @param digest 摘要算法对象
+ */
+ void release(String algorithm, XDigest digest);
+
+}
diff --git a/src/main/java/io/xjar/XDigestedInputStream.java b/src/main/java/io/xjar/XDigestedInputStream.java
new file mode 100644
index 0000000..50b9c95
--- /dev/null
+++ b/src/main/java/io/xjar/XDigestedInputStream.java
@@ -0,0 +1,35 @@
+package io.xjar;
+
+import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 摘要计算的输入流
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/3 22:31
+ */
+public class XDigestedInputStream extends JarArchiveInputStream {
+ private final XDigest xDigest;
+
+ public XDigestedInputStream(InputStream in, XDigest xDigest) {
+ super(in);
+ this.xDigest = xDigest;
+ }
+
+ public XDigestedInputStream(InputStream in, String encoding, XDigest xDigest) {
+ super(in, encoding);
+ this.xDigest = xDigest;
+ }
+
+ @Override
+ public int read(byte[] buffer, int offset, int length) throws IOException {
+ length = super.read(buffer, offset, length);
+ if (length > 0) {
+ xDigest.digest(buffer, offset, length);
+ }
+ return length;
+ }
+}
diff --git a/src/main/java/io/xjar/XDigestedOutputStream.java b/src/main/java/io/xjar/XDigestedOutputStream.java
new file mode 100644
index 0000000..c00f833
--- /dev/null
+++ b/src/main/java/io/xjar/XDigestedOutputStream.java
@@ -0,0 +1,34 @@
+package io.xjar;
+
+import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * 摘要计算的输出流
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/3 22:30
+ */
+public class XDigestedOutputStream extends JarArchiveOutputStream {
+ private final XDigest xDigest;
+
+ public XDigestedOutputStream(OutputStream out, XDigest xDigest) {
+ super(out);
+ this.xDigest = xDigest;
+ }
+
+ public XDigestedOutputStream(OutputStream out, String encoding, XDigest xDigest) {
+ super(out, encoding);
+ this.xDigest = xDigest;
+ }
+
+ @Override
+ public void write(byte[] buffer, int offset, int length) throws IOException {
+ super.write(buffer, offset, length);
+ if (length > 0) {
+ xDigest.digest(buffer, offset, length);
+ }
+ }
+}
diff --git a/src/main/java/io/xjar/XEncryptor.java b/src/main/java/io/xjar/XEncryptor.java
index ef50ddf..9867e59 100644
--- a/src/main/java/io/xjar/XEncryptor.java
+++ b/src/main/java/io/xjar/XEncryptor.java
@@ -15,6 +15,16 @@
*/
public interface XEncryptor {
+ /**
+ * 加密,将目标文件加密输出至目标文件。
+ *
+ * @param key 密钥
+ * @param src 源文件
+ * @param dest 目标文件
+ * @throws IOException I/O 异常
+ */
+ void encrypt(XKey key, String src, String dest) throws IOException;
+
/**
* 加密,将目标文件加密输出至目标文件。
*
diff --git a/src/main/java/io/xjar/XEntryDecryptor.java b/src/main/java/io/xjar/XEntryDecryptor.java
index b23244b..9a078c2 100644
--- a/src/main/java/io/xjar/XEntryDecryptor.java
+++ b/src/main/java/io/xjar/XEntryDecryptor.java
@@ -10,10 +10,6 @@ public abstract class XEntryDecryptor extends XWrappedDecryptor implements XD
protected final XEntryFilter filter;
protected final XNopDecryptor xNopDecryptor = new XNopDecryptor();
- protected XEntryDecryptor(XDecryptor xDecryptor) {
- this(xDecryptor, null);
- }
-
protected XEntryDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
super(xDecryptor);
this.filter = filter;
@@ -23,4 +19,13 @@ protected XEntryDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
public boolean filtrate(E entry) {
return filter == null || filter.filtrate(entry);
}
+
+ protected static abstract class XEntryDecryptorBuilder, B extends XEntryDecryptorBuilder> extends XWrappedDecryptorBuilder {
+ protected XEntryFilter filter;
+
+ public B filter(XEntryFilter filter) {
+ this.filter = filter;
+ return (B) this;
+ }
+ }
}
diff --git a/src/main/java/io/xjar/XEntryEncryptor.java b/src/main/java/io/xjar/XEntryEncryptor.java
index 699ea99..72459fd 100644
--- a/src/main/java/io/xjar/XEntryEncryptor.java
+++ b/src/main/java/io/xjar/XEntryEncryptor.java
@@ -10,10 +10,6 @@ public abstract class XEntryEncryptor extends XWrappedEncryptor implements XE
protected final XEntryFilter filter;
protected final XNopEncryptor xNopEncryptor = new XNopEncryptor();
- protected XEntryEncryptor(XEncryptor xEncryptor) {
- this(xEncryptor, null);
- }
-
protected XEntryEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
super(xEncryptor);
this.filter = filter;
@@ -23,4 +19,13 @@ protected XEntryEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
public boolean filtrate(E entry) {
return filter == null || filter.filtrate(entry);
}
+
+ protected static abstract class XEntryEncryptorBuilder, B extends XEntryEncryptorBuilder> extends XWrappedEncryptorBuilder {
+ protected XEntryFilter filter;
+
+ public B filter(XEntryFilter filter) {
+ this.filter = filter;
+ return (B) this;
+ }
+ }
}
diff --git a/src/main/java/io/xjar/XInjector.java b/src/main/java/io/xjar/XInjector.java
index f5eb6ef..775ed5a 100644
--- a/src/main/java/io/xjar/XInjector.java
+++ b/src/main/java/io/xjar/XInjector.java
@@ -23,11 +23,12 @@ public class XInjector {
* 往JAR包中注入XJar框架的classes
*
* @param zos jar包输出流
+ * @param ant 资源路径ANT表达式
* @throws IOException I/O 异常
*/
- public static void inject(JarArchiveOutputStream zos) throws IOException {
+ public static void inject(JarArchiveOutputStream zos, String ant) throws IOException {
Set directories = new HashSet<>();
- Enumeration resources = Loaders.ant().load("io/xjar/**");
+ Enumeration resources = Loaders.ant().load(ant);
while (resources.hasMoreElements()) {
Resource resource = resources.nextElement();
String name = resource.getName();
@@ -42,7 +43,7 @@ public static void inject(JarArchiveOutputStream zos) throws IOException {
xJarEntry.setTime(System.currentTimeMillis());
zos.putArchiveEntry(xJarEntry);
try (InputStream ris = resource.getInputStream()) {
- XKit.transfer(ris, zos);
+ XTool.transfer(ris, zos);
}
zos.closeArchiveEntry();
}
diff --git a/src/main/java/io/xjar/XJdkDecryptor.java b/src/main/java/io/xjar/XJdkDecryptor.java
index 4e06169..0b2e606 100644
--- a/src/main/java/io/xjar/XJdkDecryptor.java
+++ b/src/main/java/io/xjar/XJdkDecryptor.java
@@ -21,10 +21,16 @@ public XJdkDecryptor(String algorithm) {
this.algorithm = algorithm;
}
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ decrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void decrypt(XKey key, File src, File dest) throws IOException {
- if (!dest.getParentFile().exists() && !dest.getParentFile().mkdirs()) {
- throw new IOException("could not make directory: " + dest.getParentFile());
+ File dir = dest.getParentFile();
+ if (!dir.exists() && !dir.mkdirs() && !dir.exists()) {
+ throw new IOException("could not make directory: " + dir);
}
try (
InputStream in = new FileInputStream(src);
@@ -41,11 +47,11 @@ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getDecryptKey(), algorithm));
cis = new CipherInputStream(in, cipher);
- XKit.transfer(cis, out);
+ XTool.transfer(cis, out);
} catch (Exception e) {
throw new IOException(e);
} finally {
- XKit.close(cis);
+ XTool.close(cis);
}
}
diff --git a/src/main/java/io/xjar/XJdkEncryptor.java b/src/main/java/io/xjar/XJdkEncryptor.java
index 602e524..ee50eee 100644
--- a/src/main/java/io/xjar/XJdkEncryptor.java
+++ b/src/main/java/io/xjar/XJdkEncryptor.java
@@ -21,10 +21,16 @@ public XJdkEncryptor(String algorithm) {
this.algorithm = algorithm;
}
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ encrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void encrypt(XKey key, File src, File dest) throws IOException {
- if (!dest.getParentFile().exists() && !dest.getParentFile().mkdirs()) {
- throw new IOException("could not make directory: " + dest.getParentFile());
+ File dir = dest.getParentFile();
+ if (!dir.exists() && !dir.mkdirs() && !dir.exists()) {
+ throw new IOException("could not make directory: " + dir);
}
try (
InputStream in = new FileInputStream(src);
@@ -41,11 +47,11 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncryptKey(), algorithm));
cis = new CipherInputStream(in, cipher);
- XKit.transfer(cis, out);
+ XTool.transfer(cis, out);
} catch (Exception e) {
throw new IOException(e);
} finally {
- XKit.close(cis);
+ XTool.close(cis);
}
}
diff --git a/src/main/java/io/xjar/XJni.java b/src/main/java/io/xjar/XJni.java
new file mode 100644
index 0000000..985411a
--- /dev/null
+++ b/src/main/java/io/xjar/XJni.java
@@ -0,0 +1,53 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * JNI 接口
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/16 13:22
+ */
+public class XJni {
+ private static volatile XJni instance;
+
+ private XJni() throws IOException {
+ final ClassLoader classLoader = this.getClass().getClassLoader();
+ final URL url = classLoader.getResource("XJAR.SO");
+ if (url == null) {
+ throw new IllegalStateException("xjar library not found");
+ }
+ final File lib = File.createTempFile("XJAR", ".SO");
+ try (final InputStream in = url.openStream()) {
+ XTool.transfer(in, lib);
+ }
+ System.load(lib.getCanonicalPath());
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ XTool.delete(lib);
+ }
+ });
+ }
+
+ public static XJni getInstance() throws IOException {
+ if (instance != null) {
+ return instance;
+ }
+ synchronized (XJni.class) {
+ if (instance != null) {
+ return instance;
+ }
+ instance = new XJni();
+ return instance;
+ }
+ }
+
+ public native XKey call();
+
+}
diff --git a/src/main/java/io/xjar/XKit.java b/src/main/java/io/xjar/XKit.java
index e2ff257..d20f22c 100644
--- a/src/main/java/io/xjar/XKit.java
+++ b/src/main/java/io/xjar/XKit.java
@@ -1,209 +1,27 @@
package io.xjar;
-import io.xjar.filter.XAllEntryFilter;
-import io.xjar.filter.XAnyEntryFilter;
-import io.xjar.filter.XNotEntryFilter;
+import io.xjar.filter.*;
+import io.xjar.jar.XJarAntEntryFilter;
+import io.xjar.jar.XJarRegexEntryFilter;
import io.xjar.key.XKey;
import io.xjar.key.XSecureRandom;
import io.xjar.key.XSymmetricSecureKey;
+import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
-import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.jar.Attributes;
/**
- * XJar 工具类,包含I/O,密钥,过滤器的工具方法。
+ * 工具类
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/8 15:52
*/
public abstract class XKit implements XConstants {
- /**
- * 从输入流中读取一行字节码
- *
- * @param in 输入流
- * @return 最前面的一行字节码
- * @throws IOException I/O 异常
- */
- public static byte[] readln(InputStream in) throws IOException {
- int b = in.read();
- if (b == -1) {
- return null;
- }
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- while (b != -1) {
- switch (b) {
- case '\r':
- break;
- case '\n':
- return bos.toByteArray();
- default:
- bos.write(b);
- break;
- }
- b = in.read();
- }
- return bos.toByteArray();
- }
-
- /**
- * 往输出流中写入一行字节码
- *
- * @param out 输出流
- * @param line 一行字节码
- * @throws IOException I/O 异常
- */
- public static void writeln(OutputStream out, byte[] line) throws IOException {
- if (line == null) {
- return;
- }
- out.write(line);
- out.write('\r');
- out.write('\n');
- }
-
- /**
- * 关闭资源,等效于XKit.close(closeable, true);
- *
- * @param closeable 资源
- */
- public static void close(Closeable closeable) {
- try {
- close(closeable, true);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * 关闭资源
- *
- * @param closeable 资源
- * @param quietly 是否安静关闭,即捕获到关闭异常时是否忽略
- * @throws IOException 当quietly == false, 时捕获到的I/O异常将会往外抛
- */
- public static void close(Closeable closeable, boolean quietly) throws IOException {
- if (closeable == null) return;
- try {
- closeable.close();
- } catch (IOException e) {
- if (!quietly) throw e;
- }
- }
-
- /**
- * 输入流传输到输出流
- *
- * @param in 输入流
- * @param out 输出流
- * @return 传输长度
- * @throws IOException I/O 异常
- */
- public static long transfer(InputStream in, OutputStream out) throws IOException {
- long total = 0;
- byte[] buffer = new byte[4096];
- int length;
- while ((length = in.read(buffer)) != -1) {
- out.write(buffer, 0, length);
- total += length;
- }
- out.flush();
- return total;
- }
-
- /**
- * reader传输到writer
- *
- * @param reader reader
- * @param writer writer
- * @return 传输长度
- * @throws IOException I/O 异常
- */
- public static long transfer(Reader reader, Writer writer) throws IOException {
- long total = 0;
- char[] buffer = new char[4096];
- int length;
- while ((length = reader.read(buffer)) != -1) {
- writer.write(buffer, 0, length);
- total += length;
- }
- writer.flush();
- return total;
- }
-
- /**
- * 输入流传输到文件
- *
- * @param in 输入流
- * @param file 文件
- * @return 传输长度
- * @throws IOException I/O 异常
- */
- public static long transfer(InputStream in, File file) throws IOException {
- OutputStream out = null;
- try {
- out = new FileOutputStream(file);
- return transfer(in, out);
- } finally {
- close(out);
- }
- }
-
- /**
- * reader传输到文件
- *
- * @param reader reader
- * @param file 文件
- * @return 传输长度
- * @throws IOException I/O 异常
- */
- public static long transfer(Reader reader, File file) throws IOException {
- OutputStream out = null;
- Writer writer = null;
- try {
- out = new FileOutputStream(file);
- writer = new OutputStreamWriter(out);
- return transfer(reader, writer);
- } finally {
- close(writer);
- close(out);
- }
- }
-
- /**
- * 删除文件,如果是目录将不递归删除子文件或目录,等效于delete(file, false);
- *
- * @param file 文件/目录
- * @return 是否删除成功
- */
- public static boolean delete(File file) {
- return delete(file, false);
- }
-
- /**
- * 删除文件,如果是目录将递归删除子文件或目录
- *
- * @param file 文件/目录
- * @return 是否删除成功
- */
- public static boolean delete(File file, boolean recursively) {
- if (file.isDirectory() && recursively) {
- boolean deleted = true;
- File[] files = file.listFiles();
- for (int i = 0; files != null && i < files.length; i++) {
- deleted &= delete(files[i], true);
- }
- return deleted && file.delete();
- } else {
- return file.delete();
- }
- }
-
/**
* 根据密码生成密钥
*
@@ -262,26 +80,12 @@ public static XKey key(String algorithm, int keysize, int ivsize, String passwor
return new XSymmetricSecureKey(algorithm, keysize, ivsize, password, key.getEncoded(), iv.getEncoded());
}
- public static void retainKey(XKey key, Attributes attributes) {
- attributes.putValue(XJAR_ALGORITHM_KEY, key.getAlgorithm());
- attributes.putValue(XJAR_KEYSIZE_KEY, String.valueOf(key.getKeysize()));
- attributes.putValue(XJAR_IVSIZE_KEY, String.valueOf(key.getIvsize()));
- attributes.putValue(XJAR_PASSWORD_KEY, key.getPassword());
- }
-
- public static void removeKey(Attributes attributes) {
- attributes.remove(new Attributes.Name(XJAR_ALGORITHM_KEY));
- attributes.remove(new Attributes.Name(XJAR_KEYSIZE_KEY));
- attributes.remove(new Attributes.Name(XJAR_IVSIZE_KEY));
- attributes.remove(new Attributes.Name(XJAR_PASSWORD_KEY));
- }
-
/**
* 创建多个子过滤器AND连接的混合过滤器
*
* @return 多个子过滤器AND连接的混合过滤器
*/
- public static XAllEntryFilter all() {
+ public static XAllEntryFilter all() {
return new XAllEntryFilter<>();
}
@@ -291,7 +95,7 @@ public static XAllEntryFilter all() {
* @param filters 子过滤器
* @return 多个子过滤器AND连接的混合过滤器
*/
- public static XAllEntryFilter all(Collection extends XEntryFilter> filters) {
+ public static XAllEntryFilter all(Collection extends XEntryFilter> filters) {
return new XAllEntryFilter<>(filters);
}
@@ -300,7 +104,7 @@ public static XAllEntryFilter all(Collection extends XEntryFilter> f
*
* @return 多个子过滤器AND连接的混合过滤器
*/
- public static XAllEntryFilter and() {
+ public static XAllEntryFilter and() {
return new XAllEntryFilter<>();
}
@@ -310,7 +114,7 @@ public static XAllEntryFilter and() {
* @param filters 子过滤器
* @return 多个子过滤器AND连接的混合过滤器
*/
- public static XAllEntryFilter and(Collection extends XEntryFilter> filters) {
+ public static XAllEntryFilter and(Collection extends XEntryFilter> filters) {
return new XAllEntryFilter<>(filters);
}
@@ -319,7 +123,7 @@ public static XAllEntryFilter and(Collection extends XEntryFilter> f
*
* @return 多个子过滤器OR连接的混合过滤器
*/
- public static XAnyEntryFilter any() {
+ public static XAnyEntryFilter any() {
return new XAnyEntryFilter<>();
}
@@ -329,7 +133,7 @@ public static XAnyEntryFilter any() {
* @param filters 子过滤器
* @return 多个子过滤器OR连接的混合过滤器
*/
- public static XAnyEntryFilter any(Collection extends XEntryFilter> filters) {
+ public static XAnyEntryFilter any(Collection extends XEntryFilter> filters) {
return new XAnyEntryFilter<>(filters);
}
@@ -338,7 +142,7 @@ public static XAnyEntryFilter any(Collection extends XEntryFilter> f
*
* @return 多个子过滤器OR连接的混合过滤器
*/
- public static XAnyEntryFilter or() {
+ public static XAnyEntryFilter or() {
return new XAnyEntryFilter<>();
}
@@ -348,7 +152,7 @@ public static XAnyEntryFilter or() {
* @param filters 子过滤器
* @return 多个子过滤器OR连接的混合过滤器
*/
- public static XAnyEntryFilter or(Collection extends XEntryFilter> filters) {
+ public static XAnyEntryFilter or(Collection extends XEntryFilter> filters) {
return new XAnyEntryFilter<>(filters);
}
@@ -356,36 +160,30 @@ public static XAnyEntryFilter or(Collection extends XEntryFilter> fi
* 创建非门逻辑运算过滤器,实际上就是将委派过滤器的过滤结果取反
*
* @param filter 委派过滤器
- * @param 记录类型
* @return 非门逻辑过滤器
*/
- public static XEntryFilter not(XEntryFilter filter) {
+ public static XEntryFilter not(XEntryFilter filter) {
return new XNotEntryFilter<>(filter);
}
- public static boolean isRelative(String path) {
- return !isAbsolute(path);
- }
-
- public static boolean isAbsolute(String path) {
- if (path.startsWith("/")) {
- return true;
- }
- Set roots = new HashSet<>();
- Collections.addAll(roots, File.listRoots());
- File root = new File(path);
- while (root.getParentFile() != null) {
- root = root.getParentFile();
- }
- return roots.contains(root);
- }
-
- public static String absolutize(String path) {
- return normalize(isAbsolute(path) ? path : System.getProperty("user.dir") + File.separator + path);
+ /**
+ * 创建JAR ANT 表达式过滤器
+ *
+ * @param ant ANT 表达式
+ * @return JAR ANT 表达式过滤器
+ */
+ public static XAntEntryFilter ant(String ant) {
+ return new XJarAntEntryFilter(ant);
}
- public static String normalize(String path) {
- return path.replaceAll("[/\\\\]+", "/");
+ /**
+ * 创建JAR 正则表达式过滤器
+ *
+ * @param regex 正则表达式
+ * @return JAR 正则表达式过滤器
+ */
+ public static XRegexEntryFilter regex(String regex) {
+ return new XJarRegexEntryFilter(regex);
}
}
diff --git a/src/main/java/io/xjar/XLauncher.java b/src/main/java/io/xjar/XLauncher.java
index 331dbd0..4ebcf84 100644
--- a/src/main/java/io/xjar/XLauncher.java
+++ b/src/main/java/io/xjar/XLauncher.java
@@ -2,18 +2,6 @@
import io.xjar.key.XKey;
-import java.io.*;
-import java.net.URI;
-import java.security.CodeSource;
-import java.security.ProtectionDomain;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.Scanner;
-import java.util.Set;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
/**
* Spring-Boot 启动器
*
@@ -28,123 +16,11 @@ public class XLauncher implements XConstants {
public XLauncher(String... args) throws Exception {
this.args = args;
- String algorithm = DEFAULT_ALGORITHM;
- int keysize = DEFAULT_KEYSIZE;
- int ivsize = DEFAULT_IVSIZE;
- String password = null;
- String keypath = null;
- for (String arg : args) {
- if (arg.toLowerCase().startsWith(XJAR_ALGORITHM)) {
- algorithm = arg.substring(XJAR_ALGORITHM.length());
- }
- if (arg.toLowerCase().startsWith(XJAR_KEYSIZE)) {
- keysize = Integer.valueOf(arg.substring(XJAR_KEYSIZE.length()));
- }
- if (arg.toLowerCase().startsWith(XJAR_IVSIZE)) {
- ivsize = Integer.valueOf(arg.substring(XJAR_IVSIZE.length()));
- }
- if (arg.toLowerCase().startsWith(XJAR_PASSWORD)) {
- password = arg.substring(XJAR_PASSWORD.length());
- }
- if (arg.toLowerCase().startsWith(XJAR_KEYFILE)) {
- keypath = arg.substring(XJAR_KEYFILE.length());
- }
- }
-
- ProtectionDomain domain = this.getClass().getProtectionDomain();
- CodeSource source = domain.getCodeSource();
- URI location = (source == null ? null : source.getLocation().toURI());
- String filepath = (location == null ? null : location.getSchemeSpecificPart());
- if (filepath != null) {
- File file = new File(filepath);
- JarFile jar = new JarFile(file, false);
- Manifest manifest = jar.getManifest();
- Attributes attributes = manifest.getMainAttributes();
- if (attributes.getValue(XJAR_ALGORITHM_KEY) != null) {
- algorithm = attributes.getValue(XJAR_ALGORITHM_KEY);
- }
- if (attributes.getValue(XJAR_KEYSIZE_KEY) != null) {
- keysize = Integer.valueOf(attributes.getValue(XJAR_KEYSIZE_KEY));
- }
- if (attributes.getValue(XJAR_IVSIZE_KEY) != null) {
- ivsize = Integer.valueOf(attributes.getValue(XJAR_IVSIZE_KEY));
- }
- if (attributes.getValue(XJAR_PASSWORD_KEY) != null) {
- password = attributes.getValue(XJAR_PASSWORD_KEY);
- }
- }
-
- Properties key = null;
- File keyfile = null;
- if (keypath != null) {
- String path = XKit.absolutize(keypath);
- File file = new File(path);
- if (file.exists() && file.isFile()) {
- keyfile = file;
- try (InputStream in = new FileInputStream(file)) {
- key = new Properties();
- key.load(in);
- }
- } else {
- throw new FileNotFoundException("could not find key file at path: " + file.getCanonicalPath());
- }
- } else {
- String path = XKit.absolutize("xjar.key");
- File file = new File(path);
- if (file.exists() && file.isFile()) {
- keyfile = file;
- try (InputStream in = new FileInputStream(file)) {
- key = new Properties();
- key.load(in);
- }
- }
- }
-
- String hold = null;
- if (key != null) {
- Set names = key.stringPropertyNames();
- for (String name : names) {
- switch (name.toLowerCase()) {
- case XJAR_KEY_ALGORITHM:
- algorithm = key.getProperty(name);
- break;
- case XJAR_KEY_KEYSIZE:
- keysize = Integer.valueOf(key.getProperty(name));
- break;
- case XJAR_KEY_IVSIZE:
- ivsize = Integer.valueOf(key.getProperty(name));
- break;
- case XJAR_KEY_PASSWORD:
- password = key.getProperty(name);
- break;
- case XJAR_KEY_HOLD:
- hold = key.getProperty(name);
- default:
- break;
- }
- }
- }
-
- // 不保留密钥文件
- if (hold == null || !Arrays.asList("true", "1", "yes", "y").contains(hold.trim().toLowerCase())) {
- if (keyfile != null && keyfile.exists() && !keyfile.delete() && keyfile.exists()) {
- throw new IOException("could not delete key file: " + keyfile.getCanonicalPath());
- }
- }
-
- if (password == null && System.console() != null) {
- Console console = System.console();
- char[] chars = console.readPassword("password:");
- password = new String(chars);
- }
- if (password == null) {
- System.out.print("password:");
- Scanner scanner = new Scanner(System.in);
- password = scanner.nextLine();
- }
+ XKey xKey = XJni.getInstance().call();
+ String algorithm = xKey.getAlgorithm();
this.xDecryptor = new XJdkDecryptor(algorithm);
this.xEncryptor = new XJdkEncryptor(algorithm);
- this.xKey = XKit.key(algorithm, keysize, ivsize, password);
+ this.xKey = xKey;
}
}
diff --git a/src/main/java/io/xjar/XNopDecryptor.java b/src/main/java/io/xjar/XNopDecryptor.java
index 52a158a..bf6e513 100644
--- a/src/main/java/io/xjar/XNopDecryptor.java
+++ b/src/main/java/io/xjar/XNopDecryptor.java
@@ -12,6 +12,11 @@
*/
public class XNopDecryptor implements XDecryptor {
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ decrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void decrypt(XKey key, File src, File dest) throws IOException {
try (
@@ -24,7 +29,7 @@ public void decrypt(XKey key, File src, File dest) throws IOException {
@Override
public void decrypt(XKey key, InputStream in, OutputStream out) throws IOException {
- XKit.transfer(in, out);
+ XTool.transfer(in, out);
}
@Override
diff --git a/src/main/java/io/xjar/XNopEncryptor.java b/src/main/java/io/xjar/XNopEncryptor.java
index 0ec8fd7..17526b2 100644
--- a/src/main/java/io/xjar/XNopEncryptor.java
+++ b/src/main/java/io/xjar/XNopEncryptor.java
@@ -12,6 +12,11 @@
*/
public class XNopEncryptor implements XEncryptor {
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ encrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void encrypt(XKey key, File src, File dest) throws IOException {
try (
@@ -24,7 +29,7 @@ public void encrypt(XKey key, File src, File dest) throws IOException {
@Override
public void encrypt(XKey key, InputStream in, OutputStream out) throws IOException {
- XKit.transfer(in, out);
+ XTool.transfer(in, out);
}
@Override
diff --git a/src/main/java/io/xjar/XSignature.java b/src/main/java/io/xjar/XSignature.java
new file mode 100644
index 0000000..52c4cf0
--- /dev/null
+++ b/src/main/java/io/xjar/XSignature.java
@@ -0,0 +1,49 @@
+package io.xjar;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * 签名
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/15 10:35
+ */
+public class XSignature {
+ private final String algorithm;
+ private final byte[] signature;
+
+ public XSignature(String algorithm, byte[] signature) {
+ this.algorithm = algorithm;
+ this.signature = signature;
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public byte[] getSignature() {
+ return signature;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ XSignature that = (XSignature) o;
+ return Objects.equals(algorithm, that.algorithm) &&
+ Arrays.equals(signature, that.signature);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(algorithm);
+ result = 31 * result + Arrays.hashCode(signature);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(algorithm) + Arrays.toString(signature);
+ }
+}
diff --git a/src/main/java/io/xjar/XSmtDecryptor.java b/src/main/java/io/xjar/XSmtDecryptor.java
new file mode 100644
index 0000000..4e58d5d
--- /dev/null
+++ b/src/main/java/io/xjar/XSmtDecryptor.java
@@ -0,0 +1,42 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * 智能解密器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/4 16:10
+ */
+public class XSmtDecryptor implements XDecryptor {
+
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ new XJdkDecryptor(key.getAlgorithm()).decrypt(key, src, dest);
+ }
+
+ @Override
+ public void decrypt(XKey key, File src, File dest) throws IOException {
+ new XJdkDecryptor(key.getAlgorithm()).decrypt(key, src, dest);
+ }
+
+ @Override
+ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOException {
+ new XJdkDecryptor(key.getAlgorithm()).decrypt(key, in, out);
+ }
+
+ @Override
+ public InputStream decrypt(XKey key, InputStream in) throws IOException {
+ return new XJdkDecryptor(key.getAlgorithm()).decrypt(key, in);
+ }
+
+ @Override
+ public OutputStream decrypt(XKey key, OutputStream out) throws IOException {
+ return new XJdkDecryptor(key.getAlgorithm()).decrypt(key, out);
+ }
+}
diff --git a/src/main/java/io/xjar/XSmtEncryptor.java b/src/main/java/io/xjar/XSmtEncryptor.java
new file mode 100644
index 0000000..0160646
--- /dev/null
+++ b/src/main/java/io/xjar/XSmtEncryptor.java
@@ -0,0 +1,42 @@
+package io.xjar;
+
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * 智能加密器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/4 16:10
+ */
+public class XSmtEncryptor implements XEncryptor {
+
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ new XJdkEncryptor(key.getAlgorithm()).encrypt(key, src, dest);
+ }
+
+ @Override
+ public void encrypt(XKey key, File src, File dest) throws IOException {
+ new XJdkEncryptor(key.getAlgorithm()).encrypt(key, src, dest);
+ }
+
+ @Override
+ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOException {
+ new XJdkEncryptor(key.getAlgorithm()).encrypt(key, in, out);
+ }
+
+ @Override
+ public InputStream encrypt(XKey key, InputStream in) throws IOException {
+ return new XJdkEncryptor(key.getAlgorithm()).encrypt(key, in);
+ }
+
+ @Override
+ public OutputStream encrypt(XKey key, OutputStream out) throws IOException {
+ return new XJdkEncryptor(key.getAlgorithm()).encrypt(key, out);
+ }
+}
diff --git a/src/main/java/io/xjar/XTool.java b/src/main/java/io/xjar/XTool.java
new file mode 100644
index 0000000..f51ce7d
--- /dev/null
+++ b/src/main/java/io/xjar/XTool.java
@@ -0,0 +1,266 @@
+package io.xjar;
+
+import java.io.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * XJar 工具类,包含I/O,密钥,过滤器的工具方法。
+ */
+public abstract class XTool implements XConstants {
+
+ /**
+ * 从输入流中读取一行字节码
+ *
+ * @param in 输入流
+ * @return 最前面的一行字节码
+ * @throws IOException I/O 异常
+ */
+ public static byte[] readln(InputStream in) throws IOException {
+ int b = in.read();
+ if (b == -1) {
+ return null;
+ }
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ while (b != -1) {
+ switch (b) {
+ case '\r':
+ break;
+ case '\n':
+ return bos.toByteArray();
+ default:
+ bos.write(b);
+ break;
+ }
+ b = in.read();
+ }
+ return bos.toByteArray();
+ }
+
+ /**
+ * 往输出流中写入一行字节码
+ *
+ * @param out 输出流
+ * @param line 一行字节码
+ * @throws IOException I/O 异常
+ */
+ public static void writeln(OutputStream out, byte[] line) throws IOException {
+ if (line == null) {
+ return;
+ }
+ out.write(line);
+ out.write('\r');
+ out.write('\n');
+ }
+
+ /**
+ * 关闭资源,等效于XKit.close(closeable, true);
+ *
+ * @param closeable 资源
+ */
+ public static void close(Closeable closeable) {
+ try {
+ close(closeable, true);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 关闭资源
+ *
+ * @param closeable 资源
+ * @param quietly 是否安静关闭,即捕获到关闭异常时是否忽略
+ * @throws IOException 当quietly == false, 时捕获到的I/O异常将会往外抛
+ */
+ public static void close(Closeable closeable, boolean quietly) throws IOException {
+ if (closeable == null) return;
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ if (!quietly) throw e;
+ }
+ }
+
+ /**
+ * 输入流传输到输出流
+ *
+ * @param in 输入流
+ * @param out 输出流
+ * @return 传输长度
+ * @throws IOException I/O 异常
+ */
+ public static long transfer(InputStream in, OutputStream out) throws IOException {
+ long total = 0;
+ byte[] buffer = new byte[4096];
+ int length;
+ while ((length = in.read(buffer)) != -1) {
+ out.write(buffer, 0, length);
+ total += length;
+ }
+ out.flush();
+ return total;
+ }
+
+ /**
+ * reader传输到writer
+ *
+ * @param reader reader
+ * @param writer writer
+ * @return 传输长度
+ * @throws IOException I/O 异常
+ */
+ public static long transfer(Reader reader, Writer writer) throws IOException {
+ long total = 0;
+ char[] buffer = new char[4096];
+ int length;
+ while ((length = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, length);
+ total += length;
+ }
+ writer.flush();
+ return total;
+ }
+
+ /**
+ * 输入流传输到文件
+ *
+ * @param in 输入流
+ * @param file 文件
+ * @return 传输长度
+ * @throws IOException I/O 异常
+ */
+ public static long transfer(InputStream in, File file) throws IOException {
+ OutputStream out = null;
+ try {
+ out = new FileOutputStream(file);
+ return transfer(in, out);
+ } finally {
+ close(out);
+ }
+ }
+
+ /**
+ * reader传输到文件
+ *
+ * @param reader reader
+ * @param file 文件
+ * @return 传输长度
+ * @throws IOException I/O 异常
+ */
+ public static long transfer(Reader reader, File file) throws IOException {
+ OutputStream out = null;
+ Writer writer = null;
+ try {
+ out = new FileOutputStream(file);
+ writer = new OutputStreamWriter(out);
+ return transfer(reader, writer);
+ } finally {
+ close(writer);
+ close(out);
+ }
+ }
+
+ public static long transfer(File file, OutputStream out) throws IOException {
+ InputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ return transfer(in, out);
+ } finally {
+ close(in);
+ }
+ }
+
+ public static long transfer(File file, Writer writer) throws IOException {
+ InputStream in = null;
+ Reader reader = null;
+ try {
+ in = new FileInputStream(file);
+ reader = new InputStreamReader(in);
+ return transfer(reader, writer);
+ } finally {
+ close(reader);
+ close(in);
+ }
+ }
+
+ /**
+ * 删除文件,如果是目录将不递归删除子文件或目录,等效于delete(file, false);
+ *
+ * @param file 文件/目录
+ * @return 是否删除成功
+ */
+ public static boolean delete(File file) {
+ return delete(file, false);
+ }
+
+ /**
+ * 删除文件,如果是目录将递归删除子文件或目录
+ *
+ * @param file 文件/目录
+ * @return 是否删除成功
+ */
+ public static boolean delete(File file, boolean recursively) {
+ if (file.isDirectory() && recursively) {
+ boolean deleted = true;
+ File[] files = file.listFiles();
+ for (int i = 0; files != null && i < files.length; i++) {
+ deleted &= delete(files[i], true);
+ }
+ return deleted && file.delete();
+ } else {
+ return file.delete();
+ }
+ }
+
+ /**
+ * 判断路径是否为相对路径
+ *
+ * @param path 路径
+ * @return {@code true}: 是相对路径,{@code false}: 非相对路径
+ */
+ public static boolean isRelative(String path) {
+ return !isAbsolute(path);
+ }
+
+ /**
+ * 判断路径是否为绝对路径
+ *
+ * @param path 路径
+ * @return {@code true}: 是绝对路径,{@code false}: 非绝对路径
+ */
+ public static boolean isAbsolute(String path) {
+ if (path.startsWith("/")) {
+ return true;
+ }
+ Set roots = new HashSet<>();
+ Collections.addAll(roots, File.listRoots());
+ File root = new File(path);
+ while (root.getParentFile() != null) {
+ root = root.getParentFile();
+ }
+ return roots.contains(root);
+ }
+
+ /**
+ * 转换成绝对路径
+ *
+ * @param path 路径
+ * @return 绝对路径
+ */
+ public static String toAbsolute(String path) {
+ return toStandard(isAbsolute(path) ? path : System.getProperty("user.dir") + File.separator + path);
+ }
+
+ /**
+ * 转换标准路径
+ *
+ * @param path 路径
+ * @return 标准路径
+ */
+ public static String toStandard(String path) {
+ return path.replaceAll("[/\\\\]+", "/");
+ }
+
+}
diff --git a/src/main/java/io/xjar/XWrappedDecryptor.java b/src/main/java/io/xjar/XWrappedDecryptor.java
index 0537f01..54f50f5 100644
--- a/src/main/java/io/xjar/XWrappedDecryptor.java
+++ b/src/main/java/io/xjar/XWrappedDecryptor.java
@@ -20,6 +20,11 @@ protected XWrappedDecryptor(XDecryptor xDecryptor) {
this.xDecryptor = xDecryptor;
}
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ xDecryptor.decrypt(key, src, dest);
+ }
+
@Override
public void decrypt(XKey key, File src, File dest) throws IOException {
xDecryptor.decrypt(key, src, dest);
@@ -39,4 +44,15 @@ public InputStream decrypt(XKey key, InputStream in) throws IOException {
public OutputStream decrypt(XKey key, OutputStream out) throws IOException {
return xDecryptor.decrypt(key, out);
}
+
+ protected static abstract class XWrappedDecryptorBuilder> {
+ protected XDecryptor decryptor;
+
+ public B decryptor(XDecryptor decryptor) {
+ this.decryptor = decryptor;
+ return (B) this;
+ }
+
+ public abstract T build();
+ }
}
diff --git a/src/main/java/io/xjar/XWrappedEncryptor.java b/src/main/java/io/xjar/XWrappedEncryptor.java
index 5e2ebc1..2f11199 100644
--- a/src/main/java/io/xjar/XWrappedEncryptor.java
+++ b/src/main/java/io/xjar/XWrappedEncryptor.java
@@ -20,6 +20,11 @@ protected XWrappedEncryptor(XEncryptor xEncryptor) {
this.xEncryptor = xEncryptor;
}
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ xEncryptor.encrypt(key, src, dest);
+ }
+
@Override
public void encrypt(XKey key, File src, File dest) throws IOException {
xEncryptor.encrypt(key, src, dest);
@@ -39,4 +44,15 @@ public InputStream encrypt(XKey key, InputStream in) throws IOException {
public OutputStream encrypt(XKey key, OutputStream out) throws IOException {
return xEncryptor.encrypt(key, out);
}
+
+ protected static abstract class XWrappedEncryptorBuilder> {
+ protected XEncryptor encryptor;
+
+ public B encryptor(XEncryptor encryptor) {
+ this.encryptor = encryptor;
+ return (B) this;
+ }
+
+ public abstract T build();
+ }
}
diff --git a/src/main/java/io/xjar/boot/XBoot.java b/src/main/java/io/xjar/boot/XBoot.java
index 5dbf470..da51afc 100644
--- a/src/main/java/io/xjar/boot/XBoot.java
+++ b/src/main/java/io/xjar/boot/XBoot.java
@@ -1,11 +1,6 @@
package io.xjar.boot;
-import io.xjar.*;
-import io.xjar.key.XKey;
-import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
-
-import java.io.*;
-import java.util.zip.Deflater;
+import io.xjar.XKit;
/**
* Spring-Boot JAR包加解密工具类,在不提供过滤器的情况下会加密BOOT-INF/下的所有资源,及包括项目本身的资源和依赖jar资源。
@@ -13,972 +8,23 @@
* @author Payne 646742615@qq.com
* 2018/11/26 11:11
*/
-public class XBoot implements XConstants {
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey) throws Exception {
- encrypt(new File(src), new File(dest), xKey);
- }
+public class XBoot extends XKit {
/**
- * 加密 Spring-Boot JAR 包
+ * 获取加密器建造器
*
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
+ * @return 加密器建造器
*/
- public static void encrypt(String src, String dest, XKey xKey, int mode) throws Exception {
- encrypt(new File(src), new File(dest), xKey, mode);
+ public static XBootEncryptor.XBootEncryptorBuilder encryptor() {
+ return XBootEncryptor.builder();
}
/**
- * 加密 Spring-Boot JAR 包
+ * 获取解密器建造器
*
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @throws Exception 加密异常
+ * @return 解密器建造器
*/
- public static void encrypt(File src, File dest, XKey xKey) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey);
- }
+ public static XBootDecryptor.XBootDecryptorBuilder decryptor() {
+ return XBootDecryptor.builder();
}
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, int mode) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, mode);
- }
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(xKey.getAlgorithm()));
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, int mode) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), Deflater.DEFLATED, mode);
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), xKey, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), xKey, mode, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, filter);
- }
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, mode, filter);
- }
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, XEntryFilter filter) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), filter);
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), Deflater.DEFLATED, mode, filter);
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- encrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, password, algorithm, keysize, ivsize);
- }
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password) throws Exception {
- encrypt(in, out, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm) throws Exception {
- encrypt(in, out, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize) throws Exception {
- encrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(algorithm));
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, password, algorithm, keysize, ivsize, filter);
- }
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 Spring-Boot JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- XBootEncryptor xBootEncryptor = new XBootEncryptor(new XJdkEncryptor(algorithm), filter);
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xBootEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, XKey xKey) throws Exception {
- decrypt(new File(src), new File(dest), xKey);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, XKey xKey) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, xKey);
- }
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, XKey xKey) throws Exception {
- XBootDecryptor xBootDecryptor = new XBootDecryptor(new XJdkDecryptor(xKey.getAlgorithm()));
- xBootDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, XKey xKey, XEntryFilter filter) throws Exception {
- decrypt(new File(src), new File(dest), xKey, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, XKey xKey, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, xKey, filter);
- }
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, XKey xKey, XEntryFilter filter) throws Exception {
- XBootDecryptor xBootDecryptor = new XBootDecryptor(new XJdkDecryptor(xKey.getAlgorithm()), filter);
- xBootDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- decrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, password, algorithm, keysize, ivsize);
- }
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password) throws Exception {
- decrypt(in, out, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm) throws Exception {
- decrypt(in, out, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize) throws Exception {
- decrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize) throws Exception {
- XBootDecryptor xBootDecryptor = new XBootDecryptor(new XJdkDecryptor(algorithm));
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xBootDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- decrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, password, algorithm, keysize, ivsize, filter);
- }
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 解密 Spring-Boot JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- XBootDecryptor xBootDecryptor = new XBootDecryptor(new XJdkDecryptor(algorithm), filter);
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xBootDecryptor.decrypt(xKey, in, out);
- }
-
}
diff --git a/src/main/java/io/xjar/boot/XBootClassLoader.java b/src/main/java/io/xjar/boot/XBootClassLoader.java
index aa2be80..b2ecb02 100644
--- a/src/main/java/io/xjar/boot/XBootClassLoader.java
+++ b/src/main/java/io/xjar/boot/XBootClassLoader.java
@@ -2,7 +2,7 @@
import io.xjar.XDecryptor;
import io.xjar.XEncryptor;
-import io.xjar.XKit;
+import io.xjar.XTool;
import io.xjar.key.XKey;
import org.springframework.boot.loader.LaunchedURLClassLoader;
@@ -64,7 +64,7 @@ protected Class> findClass(String name) throws ClassNotFoundException {
}
try (InputStream in = resource.openStream()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- XKit.transfer(in, bos);
+ XTool.transfer(in, bos);
byte[] bytes = bos.toByteArray();
return defineClass(name, bytes, 0, bytes.length);
} catch (Throwable t) {
diff --git a/src/main/java/io/xjar/boot/XBootDecryptor.java b/src/main/java/io/xjar/boot/XBootDecryptor.java
index c4ea690..c9a582b 100644
--- a/src/main/java/io/xjar/boot/XBootDecryptor.java
+++ b/src/main/java/io/xjar/boot/XBootDecryptor.java
@@ -21,36 +21,14 @@
* @author Payne 646742615@qq.com
* 2018/11/22 15:27
*/
-public class XBootDecryptor extends XEntryDecryptor implements XDecryptor, XConstants {
+public class XBootDecryptor extends XArchiveDecryptor implements XDecryptor, XConstants {
private final int level;
- public XBootDecryptor(XDecryptor xEncryptor) {
- this(xEncryptor, new XJarAllEntryFilter());
- }
-
- public XBootDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
- this(xDecryptor, Deflater.DEFLATED, filter);
- }
-
- public XBootDecryptor(XDecryptor xEncryptor, int level) {
- this(xEncryptor, level, new XJarAllEntryFilter());
- }
-
- public XBootDecryptor(XDecryptor xDecryptor, int level, XEntryFilter filter) {
+ public XBootDecryptor(XDecryptor xDecryptor, XEntryFilter filter, int level) {
super(xDecryptor, filter);
this.level = level;
}
- @Override
- public void decrypt(XKey key, File src, File dest) throws IOException {
- try (
- FileInputStream fis = new FileInputStream(src);
- FileOutputStream fos = new FileOutputStream(dest)
- ) {
- decrypt(key, fis, fos);
- }
- }
-
@Override
public void decrypt(XKey key, InputStream in, OutputStream out) throws IOException {
JarArchiveInputStream zis = null;
@@ -61,7 +39,11 @@ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
zos.setLevel(level);
XUnclosedInputStream nis = new XUnclosedInputStream(zis);
XUnclosedOutputStream nos = new XUnclosedOutputStream(zos);
- XJarDecryptor xJarDecryptor = new XJarDecryptor(xDecryptor, level, filter);
+ XJarDecryptor xJarDecryptor = XJarDecryptor.builder()
+ .decryptor(xDecryptor)
+ .filter(filter)
+ .level(level)
+ .build();
JarArchiveEntry entry;
while ((entry = zis.getNextJarEntry()) != null) {
if (entry.getName().startsWith(XJAR_SRC_DIR)
@@ -85,7 +67,6 @@ else if (entry.getName().equals(META_INF_MANIFEST)) {
attributes.putValue("Main-Class", mainClass);
attributes.remove(new Attributes.Name("Boot-Main-Class"));
}
- XKit.removeKey(attributes);
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
@@ -100,7 +81,7 @@ else if (entry.getName().startsWith(BOOT_INF_CLASSES)) {
boolean filtered = filtrate(xBootJarArchiveEntry);
XDecryptor decryptor = filtered ? xDecryptor : xNopDecryptor;
try (OutputStream eos = decryptor.decrypt(key, nos)) {
- XKit.transfer(nis, eos);
+ XTool.transfer(nis, eos);
}
}
// BOOT-INF/lib/**
@@ -115,23 +96,45 @@ else if (entry.getName().startsWith(BOOT_INF_LIB)) {
jar.setCrc(cos.getChecksum().getValue());
zos.putArchiveEntry(jar);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- XKit.transfer(bis, nos);
+ XTool.transfer(bis, nos);
}
// OTHER
else {
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
- XKit.transfer(nis, nos);
+ XTool.transfer(nis, nos);
}
zos.closeArchiveEntry();
}
zos.finish();
} finally {
- XKit.close(zis);
- XKit.close(zos);
+ XTool.close(zis);
+ XTool.close(zos);
}
}
+ public static XBootDecryptorBuilder builder() {
+ return new XBootDecryptorBuilder();
+ }
+
+ public static class XBootDecryptorBuilder extends XArchiveDecryptorBuilder {
+ private int level = Deflater.DEFLATED;
+
+ {
+ decryptor(new XSmtDecryptor());
+ filter(new XJarAllEntryFilter());
+ }
+
+ public XBootDecryptorBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ @Override
+ public XBootDecryptor build() {
+ return new XBootDecryptor(decryptor, filter, level);
+ }
+ }
}
diff --git a/src/main/java/io/xjar/boot/XBootEncryptor.java b/src/main/java/io/xjar/boot/XBootEncryptor.java
index 60ac909..018c261 100644
--- a/src/main/java/io/xjar/boot/XBootEncryptor.java
+++ b/src/main/java/io/xjar/boot/XBootEncryptor.java
@@ -1,6 +1,8 @@
package io.xjar.boot;
import io.xjar.*;
+import io.xjar.compiler.XAwareCompiler;
+import io.xjar.digest.XJdkDigestFactory;
import io.xjar.jar.XJarAllEntryFilter;
import io.xjar.jar.XJarEncryptor;
import io.xjar.key.XKey;
@@ -9,6 +11,7 @@
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
import java.io.*;
+import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -25,7 +28,7 @@
* @author Payne 646742615@qq.com
* 2018/11/22 15:27
*/
-public class XBootEncryptor extends XEntryEncryptor implements XEncryptor, XConstants {
+public class XBootEncryptor extends XArchiveEncryptor implements XEncryptor, XConstants {
private final Map map = new HashMap<>();
{
@@ -38,42 +41,16 @@ public class XBootEncryptor extends XEntryEncryptor implements
}
private final int level;
- private final int mode;
+ private final XDigestFactory digestFactory;
+ private final String digestAlgorithm;
+ private final XCompiler compiler;
- public XBootEncryptor(XEncryptor xEncryptor) {
- this(xEncryptor, new XJarAllEntryFilter());
- }
-
- public XBootEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
- this(xEncryptor, Deflater.DEFLATED, filter);
- }
-
- public XBootEncryptor(XEncryptor xEncryptor, int level) {
- this(xEncryptor, level, new XJarAllEntryFilter());
- }
-
- public XBootEncryptor(XEncryptor xEncryptor, int level, XEntryFilter filter) {
- this(xEncryptor, level, MODE_NORMAL, filter);
- }
-
- public XBootEncryptor(XEncryptor xEncryptor, int level, int mode) {
- this(xEncryptor, level, mode, new XJarAllEntryFilter());
- }
-
- public XBootEncryptor(XEncryptor xEncryptor, int level, int mode, XEntryFilter filter) {
+ public XBootEncryptor(XEncryptor xEncryptor, XEntryFilter filter, int level, XDigestFactory digestFactory, String digestAlgorithm, XCompiler compiler) {
super(xEncryptor, filter);
this.level = level;
- this.mode = mode;
- }
-
- @Override
- public void encrypt(XKey key, File src, File dest) throws IOException {
- try (
- FileInputStream fis = new FileInputStream(src);
- FileOutputStream fos = new FileOutputStream(dest)
- ) {
- encrypt(key, fis, fos);
- }
+ this.digestFactory = digestFactory;
+ this.digestAlgorithm = digestAlgorithm;
+ this.compiler = compiler;
}
@Override
@@ -81,13 +58,22 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
JarArchiveInputStream zis = null;
JarArchiveOutputStream zos = null;
Set indexes = new LinkedHashSet<>();
+ XDigest digest = null;
try {
+ digest = digestFactory.acquire(digestAlgorithm);
zis = new JarArchiveInputStream(in);
- zos = new JarArchiveOutputStream(out);
+ zos = new XDigestedOutputStream(out, digest);
zos.setLevel(level);
XUnclosedInputStream nis = new XUnclosedInputStream(zis);
XUnclosedOutputStream nos = new XUnclosedOutputStream(zos);
- XJarEncryptor xJarEncryptor = new XJarEncryptor(xEncryptor, level, filter);
+ XJarEncryptor xJarEncryptor = XJarEncryptor.builder()
+ .encryptor(xEncryptor)
+ .filter(filter)
+ .level(level)
+ .digestFactory(digestFactory)
+ .digestAlgorithm(digestAlgorithm)
+ .compiler(compiler)
+ .build();
JarArchiveEntry entry;
Manifest manifest = null;
while ((entry = zis.getNextJarEntry()) != null) {
@@ -112,9 +98,6 @@ else if (entry.getName().equals(META_INF_MANIFEST)) {
attributes.putValue("Boot-Main-Class", mainClass);
attributes.putValue("Main-Class", map.get(mainClass));
}
- if ((mode & FLAG_DANGER) == FLAG_DANGER) {
- XKit.retainKey(key, attributes);
- }
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
@@ -132,7 +115,7 @@ else if (entry.getName().startsWith(BOOT_INF_CLASSES)) {
}
XEncryptor encryptor = filtered ? xEncryptor : xNopEncryptor;
try (OutputStream eos = encryptor.encrypt(key, nos)) {
- XKit.transfer(nis, eos);
+ XTool.transfer(nis, eos);
}
}
// BOOT-INF/lib/**
@@ -147,14 +130,14 @@ else if (entry.getName().startsWith(BOOT_INF_LIB)) {
jar.setCrc(cos.getChecksum().getValue());
zos.putArchiveEntry(jar);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- XKit.transfer(bis, nos);
+ XTool.transfer(bis, nos);
}
// OTHER
else {
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
- XKit.transfer(nis, nos);
+ XTool.transfer(nis, nos);
}
zos.closeArchiveEntry();
}
@@ -177,14 +160,67 @@ else if (entry.getName().startsWith(BOOT_INF_LIB)) {
String mainClass = manifest != null && manifest.getMainAttributes() != null ? manifest.getMainAttributes().getValue("Main-Class") : null;
if (mainClass != null) {
- XInjector.inject(zos);
+ XInjector.inject(zos, "io/xjar/**");
+ byte[] signature = digest.finish();
+ XSignature xSignature = new XSignature(digestAlgorithm, signature);
+ File lib = compiler.compile(key, xSignature);
+ JarArchiveEntry xLibEntry = new JarArchiveEntry("XJAR.SO");
+ xLibEntry.setTime(System.currentTimeMillis());
+ zos.putArchiveEntry(xLibEntry);
+ XTool.transfer(lib, zos);
+ zos.closeArchiveEntry();
}
zos.finish();
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e);
} finally {
- XKit.close(zis);
- XKit.close(zos);
+ XTool.close(zis);
+ XTool.close(zos);
+ if (digest != null) {
+ digestFactory.release(digestAlgorithm, digest);
+ }
}
}
+ public static XBootEncryptorBuilder builder() {
+ return new XBootEncryptorBuilder();
+ }
+
+ public static class XBootEncryptorBuilder extends XArchiveEncryptorBuilder {
+ private int level = Deflater.DEFLATED;
+ private XDigestFactory digestFactory = new XJdkDigestFactory();
+ private String digestAlgorithm = "MD5";
+ private XCompiler compiler = new XAwareCompiler();
+
+ {
+ encryptor(new XSmtEncryptor());
+ filter(new XJarAllEntryFilter());
+ }
+
+ public XBootEncryptorBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ public XBootEncryptorBuilder digestFactory(XDigestFactory digestFactory) {
+ this.digestFactory = digestFactory;
+ return this;
+ }
+
+ public XBootEncryptorBuilder digestAlgorithm(String digestAlgorithm) {
+ this.digestAlgorithm = digestAlgorithm;
+ return this;
+ }
+
+ public XBootEncryptorBuilder compiler(XCompiler compiler) {
+ this.compiler = compiler;
+ return this;
+ }
+
+ @Override
+ public XBootEncryptor build() {
+ return new XBootEncryptor(encryptor, filter, level, digestFactory, digestAlgorithm, compiler);
+ }
+ }
}
diff --git a/src/main/java/io/xjar/compiler/XAwareCompiler.java b/src/main/java/io/xjar/compiler/XAwareCompiler.java
new file mode 100644
index 0000000..27f07f6
--- /dev/null
+++ b/src/main/java/io/xjar/compiler/XAwareCompiler.java
@@ -0,0 +1,42 @@
+package io.xjar.compiler;
+
+import io.xjar.XCompiler;
+import io.xjar.XSignature;
+import io.xjar.key.XKey;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * 自知 编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/16 11:10
+ */
+public class XAwareCompiler implements XCompiler {
+ private static final String WINDOWS = "WINDOWS";
+ private static final String LINUX = "LINUX";
+ private static final String MAC = "MAC";
+
+ private final XCompiler delegate;
+
+ public XAwareCompiler() {
+ String os = System.getProperty("os.name");
+ if (os == null) {
+ throw new IllegalStateException("unknown current operation system");
+ } else if (os.toUpperCase().startsWith(WINDOWS)) {
+ this.delegate = new XWindowsCompiler();
+ } else if (os.toUpperCase().startsWith(LINUX)) {
+ this.delegate = new XLinuxCompiler();
+ } else if (os.toUpperCase().startsWith(MAC)) {
+ this.delegate = new XMacCompiler();
+ } else {
+ throw new IllegalStateException("unsupported operation system: " + os);
+ }
+ }
+
+ @Override
+ public File compile(XKey xKey, XSignature xSignature) throws IOException {
+ return delegate.compile(xKey, xSignature);
+ }
+}
diff --git a/src/main/java/io/xjar/compiler/XLinuxCompiler.java b/src/main/java/io/xjar/compiler/XLinuxCompiler.java
new file mode 100644
index 0000000..fa9115d
--- /dev/null
+++ b/src/main/java/io/xjar/compiler/XLinuxCompiler.java
@@ -0,0 +1,47 @@
+package io.xjar.compiler;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Linux 编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/16 10:47
+ */
+public class XLinuxCompiler extends XPlatformCompiler {
+ protected String gccPath = "g++";
+ protected String jdkRoot = new File(System.getProperty("java.home")).getParent();
+
+ @Override
+ protected String convert(List src, String lib) {
+ StringBuilder command = new StringBuilder();
+ command.append(gccPath.replace(" ", "\\ "));
+ command.append(" ").append("-fPIC");
+ command.append(" ").append("-shared");
+ command.append(" ").append("-o");
+ command.append(" ").append(lib);
+ for (String path : src) {
+ command.append(" ").append(path.replace(" ", "\\ "));
+ }
+ command.append(" ").append("-I ").append(jdkRoot.replace(" ", "\\ ")).append(File.separator).append("include");
+ command.append(" ").append("-I ").append(jdkRoot.replace(" ", "\\ ")).append(File.separator).append("include").append(File.separator).append("linux");
+ return command.toString();
+ }
+
+ public String getGccPath() {
+ return gccPath;
+ }
+
+ public void setGccPath(String gccPath) {
+ this.gccPath = gccPath;
+ }
+
+ public String getJdkRoot() {
+ return jdkRoot;
+ }
+
+ public void setJdkRoot(String jdkRoot) {
+ this.jdkRoot = jdkRoot;
+ }
+}
diff --git a/src/main/java/io/xjar/compiler/XMacCompiler.java b/src/main/java/io/xjar/compiler/XMacCompiler.java
new file mode 100644
index 0000000..eb9150c
--- /dev/null
+++ b/src/main/java/io/xjar/compiler/XMacCompiler.java
@@ -0,0 +1,47 @@
+package io.xjar.compiler;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Mac 编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/16 10:48
+ */
+public class XMacCompiler extends XPlatformCompiler {
+ protected String gccPath = "g++";
+ protected String jdkRoot = new File(System.getProperty("java.home")).getParent();
+
+ @Override
+ protected String convert(List src, String lib) {
+ StringBuilder command = new StringBuilder();
+ command.append(gccPath.replace(" ", "\\ "));
+ command.append(" ").append("-fPIC");
+ command.append(" ").append("-shared");
+ command.append(" ").append("-o");
+ command.append(" ").append(lib);
+ for (String path : src) {
+ command.append(" ").append(path.replace(" ", "\\ "));
+ }
+ command.append(" ").append("-I ").append(jdkRoot.replace(" ", "\\ ")).append(File.separator).append("include");
+ command.append(" ").append("-I ").append(jdkRoot.replace(" ", "\\ ")).append(File.separator).append("include").append(File.separator).append("darwin");
+ return command.toString();
+ }
+
+ public String getGccPath() {
+ return gccPath;
+ }
+
+ public void setGccPath(String gccPath) {
+ this.gccPath = gccPath;
+ }
+
+ public String getJdkRoot() {
+ return jdkRoot;
+ }
+
+ public void setJdkRoot(String jdkRoot) {
+ this.jdkRoot = jdkRoot;
+ }
+}
diff --git a/src/main/java/io/xjar/compiler/XPlatformCompiler.java b/src/main/java/io/xjar/compiler/XPlatformCompiler.java
new file mode 100644
index 0000000..ce22c38
--- /dev/null
+++ b/src/main/java/io/xjar/compiler/XPlatformCompiler.java
@@ -0,0 +1,130 @@
+package io.xjar.compiler;
+
+import io.loadkit.Loaders;
+import io.loadkit.Resource;
+import io.xjar.XCompiler;
+import io.xjar.XSignature;
+import io.xjar.XTool;
+import io.xjar.key.XKey;
+import org.beetl.core.Configuration;
+import org.beetl.core.GroupTemplate;
+import org.beetl.core.ResourceLoader;
+import org.beetl.core.Template;
+import org.beetl.core.resource.ClasspathResourceLoader;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 标准编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/15 10:42
+ */
+public abstract class XPlatformCompiler implements XCompiler {
+ protected String libName = "XJAR.SO";
+ protected String srcRoot = "io/xjar/jni";
+ protected String tmpRoot = System.getProperty("java.io.tmpdir");
+
+ @Override
+ public File compile(XKey xKey, XSignature xSignature) throws IOException {
+ try {
+ File dir = new File(tmpRoot, UUID.randomUUID().toString());
+ if (!dir.exists() && !dir.mkdirs() && !dir.exists()) {
+ throw new IOException("could not make directory: " + dir);
+ }
+
+ List src = render(xKey, xSignature, srcRoot, dir);
+ String cmd = convert(src, libName);
+
+ Process process = Runtime.getRuntime().exec(cmd, null, dir);
+ int code = process.waitFor();
+ if (code != 0) {
+ XTool.transfer(process.getErrorStream(), System.err);
+ throw new IllegalStateException("error occurred while compiling c++ lib with code: " + code);
+ }
+
+ return new File(dir, libName);
+ } catch (IOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new IOException(ex);
+ }
+ }
+
+ /**
+ * 转换编译命令
+ *
+ * @param src 源码列表
+ * @param lib 目标类库
+ * @return 编译命令
+ */
+ protected abstract String convert(List src, String lib);
+
+ /**
+ * 渲染源码文件
+ *
+ * @param xKey 密钥
+ * @param xSignature 签名
+ * @param path 资源根路径
+ * @param dir 目录
+ * @return 源码文件相对路径列表
+ * @throws IOException I/O异常
+ */
+ protected List render(XKey xKey, XSignature xSignature, String path, File dir) throws IOException {
+ List sources = new ArrayList<>();
+ ResourceLoader resourceLoader = new ClasspathResourceLoader();
+ Configuration configuration = Configuration.defaultConfiguration();
+ GroupTemplate groupTemplate = new GroupTemplate(resourceLoader, configuration);
+ Enumeration resources = Loaders.ant().load(path + "/**/*");
+ while (resources.hasMoreElements()) {
+ Resource resource = resources.nextElement();
+ String name = resource.getName();
+ if (name.endsWith(".cpp")) {
+ sources.add(name);
+ }
+ File file = new File(dir, name);
+ File folder = file.getParentFile();
+ if (!folder.exists() && !folder.mkdirs() && !folder.exists()) {
+ throw new IOException("could not make directory: " + folder);
+ }
+ Template template = groupTemplate.getTemplate(name);
+ template.binding("xKey", xKey);
+ template.binding("xSignature", xSignature);
+ try (OutputStream out = new FileOutputStream(file)) {
+ template.renderTo(out);
+ }
+ }
+ return sources;
+ }
+
+ public String getLibName() {
+ return libName;
+ }
+
+ public void setLibName(String libName) {
+ this.libName = libName;
+ }
+
+ public String getSrcRoot() {
+ return srcRoot;
+ }
+
+ public void setSrcRoot(String srcRoot) {
+ this.srcRoot = srcRoot;
+ }
+
+ public String getTmpRoot() {
+ return tmpRoot;
+ }
+
+ public void setTmpRoot(String tmpRoot) {
+ this.tmpRoot = tmpRoot;
+ }
+}
diff --git a/src/main/java/io/xjar/compiler/XWindowsCompiler.java b/src/main/java/io/xjar/compiler/XWindowsCompiler.java
new file mode 100644
index 0000000..8f09e9f
--- /dev/null
+++ b/src/main/java/io/xjar/compiler/XWindowsCompiler.java
@@ -0,0 +1,47 @@
+package io.xjar.compiler;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Windows 编译器
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/16 10:39
+ */
+public class XWindowsCompiler extends XPlatformCompiler {
+ protected String gccPath = "g++";
+ protected String jdkRoot = new File(System.getProperty("java.home")).getParent();
+
+ @Override
+ protected String convert(List src, String lib) {
+ StringBuilder command = new StringBuilder();
+ command.append("\"").append(gccPath).append("\"");
+ command.append(" ").append("-fPIC");
+ command.append(" ").append("-shared");
+ command.append(" ").append("-o");
+ command.append(" ").append("\"").append(lib).append("\"");
+ for (String path : src) {
+ command.append(" ").append("\"").append(path).append("\"");
+ }
+ command.append(" ").append("-I \"").append(jdkRoot).append(File.separator).append("include").append("\"");
+ command.append(" ").append("-I \"").append(jdkRoot).append(File.separator).append("include").append(File.separator).append("win32").append("\"");
+ return command.toString();
+ }
+
+ public String getGccPath() {
+ return gccPath;
+ }
+
+ public void setGccPath(String gccPath) {
+ this.gccPath = gccPath;
+ }
+
+ public String getJdkRoot() {
+ return jdkRoot;
+ }
+
+ public void setJdkRoot(String jdkRoot) {
+ this.jdkRoot = jdkRoot;
+ }
+}
diff --git a/src/main/java/io/xjar/digest/XJdkDigest.java b/src/main/java/io/xjar/digest/XJdkDigest.java
new file mode 100644
index 0000000..dcd804d
--- /dev/null
+++ b/src/main/java/io/xjar/digest/XJdkDigest.java
@@ -0,0 +1,35 @@
+package io.xjar.digest;
+
+import io.xjar.XDigest;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * JDK内置摘要算法
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/3 22:27
+ */
+public class XJdkDigest implements XDigest {
+ private final MessageDigest md;
+
+ public XJdkDigest(String algorithm) throws NoSuchAlgorithmException {
+ md = MessageDigest.getInstance(algorithm);
+ }
+
+ @Override
+ public void digest(byte[] buf, int off, int len) {
+ md.update(buf, off, len);
+ }
+
+ @Override
+ public byte[] finish() {
+ return md.digest();
+ }
+
+ @Override
+ public void resume() {
+ md.reset();
+ }
+}
diff --git a/src/main/java/io/xjar/digest/XJdkDigestFactory.java b/src/main/java/io/xjar/digest/XJdkDigestFactory.java
new file mode 100644
index 0000000..d5df286
--- /dev/null
+++ b/src/main/java/io/xjar/digest/XJdkDigestFactory.java
@@ -0,0 +1,20 @@
+package io.xjar.digest;
+
+import io.xjar.XDigest;
+import io.xjar.XDigestFactory;
+
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * JDK内置摘要算法对象工厂
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/5 10:22
+ */
+public class XJdkDigestFactory extends XRecycledDigestFactory implements XDigestFactory {
+
+ @Override
+ protected XDigest produce(String algorithm) throws NoSuchAlgorithmException {
+ return new XJdkDigest(algorithm);
+ }
+}
diff --git a/src/main/java/io/xjar/digest/XRecycledDigestFactory.java b/src/main/java/io/xjar/digest/XRecycledDigestFactory.java
new file mode 100644
index 0000000..e981c16
--- /dev/null
+++ b/src/main/java/io/xjar/digest/XRecycledDigestFactory.java
@@ -0,0 +1,51 @@
+package io.xjar.digest;
+
+import io.xjar.XDigest;
+import io.xjar.XDigestFactory;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 重复利用的摘要算法对象工厂
+ *
+ * @author Payne 646742615@qq.com
+ * 2019/7/9 10:50
+ */
+public abstract class XRecycledDigestFactory implements XDigestFactory {
+ private final ConcurrentMap> pool = new ConcurrentHashMap<>();
+
+ /**
+ * 生产一个新的摘要算法对象
+ *
+ * @param algorithm 摘要算法
+ * @return 摘要算法对象
+ * @throws NoSuchAlgorithmException 摘要算法不支持
+ */
+ protected abstract XDigest produce(String algorithm) throws NoSuchAlgorithmException;
+
+ @Override
+ public XDigest acquire(String algorithm) throws NoSuchAlgorithmException {
+ Queue queue = pool.get(algorithm);
+ XDigest digest = queue != null ? queue.poll() : null;
+ if (digest == null) {
+ digest = produce(algorithm);
+ }
+ digest.resume();
+ return digest;
+ }
+
+ @Override
+ public void release(String algorithm, XDigest digest) {
+ digest.resume();
+ Queue queue = new ConcurrentLinkedQueue<>();
+ queue.offer(digest);
+ Queue old = pool.putIfAbsent(algorithm, queue);
+ if (old != null) {
+ old.offer(digest);
+ }
+ }
+}
diff --git a/src/main/java/io/xjar/dir/XDirDecryptor.java b/src/main/java/io/xjar/dir/XDirDecryptor.java
index fa6c830..af4012d 100644
--- a/src/main/java/io/xjar/dir/XDirDecryptor.java
+++ b/src/main/java/io/xjar/dir/XDirDecryptor.java
@@ -24,6 +24,11 @@ public XDirDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
super(xDecryptor, filter);
}
+ @Override
+ public void decrypt(XKey key, String src, String dest) throws IOException {
+ decrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void decrypt(XKey key, File src, File dest) throws IOException {
if (src.isFile()) {
diff --git a/src/main/java/io/xjar/dir/XDirEncryptor.java b/src/main/java/io/xjar/dir/XDirEncryptor.java
index a33192d..6db82e6 100644
--- a/src/main/java/io/xjar/dir/XDirEncryptor.java
+++ b/src/main/java/io/xjar/dir/XDirEncryptor.java
@@ -24,6 +24,11 @@ public XDirEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
super(xEncryptor, filter);
}
+ @Override
+ public void encrypt(XKey key, String src, String dest) throws IOException {
+ encrypt(key, new File(src), new File(dest));
+ }
+
@Override
public void encrypt(XKey key, File src, File dest) throws IOException {
if (src.isFile()) {
diff --git a/src/main/java/io/xjar/jar/XJar.java b/src/main/java/io/xjar/jar/XJar.java
index b0fb7af..cd2d720 100644
--- a/src/main/java/io/xjar/jar/XJar.java
+++ b/src/main/java/io/xjar/jar/XJar.java
@@ -1,11 +1,6 @@
package io.xjar.jar;
-import io.xjar.*;
-import io.xjar.key.XKey;
-import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
-
-import java.io.*;
-import java.util.zip.Deflater;
+import io.xjar.XKit;
/**
* 普通JAR包加解密工具类
@@ -13,972 +8,24 @@
* @author Payne 646742615@qq.com
* 2018/11/26 11:11
*/
-public class XJar implements XConstants {
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey) throws Exception {
- encrypt(new File(src), new File(dest), xKey);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey, int mode) throws Exception {
- encrypt(new File(src), new File(dest), xKey, mode);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, int mode) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, mode);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(xKey.getAlgorithm()));
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param mode 加密模式
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, int mode) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), Deflater.DEFLATED, mode);
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), xKey, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), xKey, mode, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, filter);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, xKey, mode, filter);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, XEntryFilter filter) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), filter);
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param xKey 密钥
- * @param mode 加密模式
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, XKey xKey, int mode, XEntryFilter filter) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(xKey.getAlgorithm()), Deflater.DEFLATED, mode, filter);
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- encrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, password, algorithm, keysize, ivsize);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password) throws Exception {
- encrypt(in, out, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm) throws Exception {
- encrypt(in, out, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize) throws Exception {
- encrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(algorithm));
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- encrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param src 原文包
- * @param dest 加密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- encrypt(in, out, password, algorithm, keysize, ivsize, filter);
- }
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- encrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 加密 普通 JAR 包
- *
- * @param in 原文包输入流
- * @param out 加密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 加密异常
- */
- public static void encrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- XJarEncryptor xJarEncryptor = new XJarEncryptor(new XJdkEncryptor(algorithm), filter);
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xJarEncryptor.encrypt(xKey, in, out);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, XKey xKey) throws Exception {
- decrypt(new File(src), new File(dest), xKey);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, XKey xKey) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, xKey);
- }
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param xKey 密钥
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, XKey xKey) throws Exception {
- XJarDecryptor xJarDecryptor = new XJarDecryptor(new XJdkDecryptor(xKey.getAlgorithm()));
- xJarDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, XKey xKey, XEntryFilter filter) throws Exception {
- decrypt(new File(src), new File(dest), xKey, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, XKey xKey, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, xKey, filter);
- }
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param xKey 密钥
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, XKey xKey, XEntryFilter filter) throws Exception {
- XJarDecryptor xJarDecryptor = new XJarDecryptor(new XJdkDecryptor(xKey.getAlgorithm()), filter);
- xJarDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- decrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, password, algorithm, keysize, ivsize);
- }
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password) throws Exception {
- decrypt(in, out, password, DEFAULT_ALGORITHM);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm) throws Exception {
- decrypt(in, out, password, algorithm, DEFAULT_KEYSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize) throws Exception {
- decrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize) throws Exception {
- XJarDecryptor xJarDecryptor = new XJarDecryptor(new XJdkDecryptor(algorithm));
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xJarDecryptor.decrypt(xKey, in, out);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(String src, String dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- decrypt(new File(src), new File(dest), password, algorithm, keysize, ivsize, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(src, dest, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param src 加密包
- * @param dest 解密包
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(File src, File dest, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- try (
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest)
- ) {
- decrypt(in, out, password, algorithm, keysize, ivsize, filter);
- }
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, DEFAULT_ALGORITHM, filter);
- }
-
- /**
- * 解密 普通 JAR 包
- *
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param filter 过滤器
- * @throws Exception 解密异常
- */
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, algorithm, DEFAULT_KEYSIZE, filter);
- }
+public class XJar extends XKit {
/**
- * 解密 普通 JAR 包
+ * 获取加密器建造器
*
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param filter 过滤器
- * @throws Exception 解密异常
+ * @return 加密器建造器
*/
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, XEntryFilter filter) throws Exception {
- decrypt(in, out, password, algorithm, keysize, DEFAULT_IVSIZE, filter);
+ public static XJarEncryptor.XJarEncryptorBuilder encryptor() {
+ return XJarEncryptor.builder();
}
/**
- * 解密 普通 JAR 包
+ * 获取解密器建造器
*
- * @param in 加密包输入流
- * @param out 解密包输出流
- * @param password 密码
- * @param algorithm 加密算法
- * @param keysize 密钥长度
- * @param ivsize 向量长度
- * @param filter 过滤器
- * @throws Exception 解密异常
+ * @return 解密器建造器
*/
- public static void decrypt(InputStream in, OutputStream out, String password, String algorithm, int keysize, int ivsize, XEntryFilter filter) throws Exception {
- XJarDecryptor xJarDecryptor = new XJarDecryptor(new XJdkDecryptor(algorithm), filter);
- XKey xKey = XKit.key(algorithm, keysize, ivsize, password);
- xJarDecryptor.decrypt(xKey, in, out);
+ public static XJarDecryptor.XJarDecryptorBuilder decryptor() {
+ return XJarDecryptor.builder();
}
}
diff --git a/src/main/java/io/xjar/jar/XJarClassLoader.java b/src/main/java/io/xjar/jar/XJarClassLoader.java
index 6c329c0..3f0afd8 100644
--- a/src/main/java/io/xjar/jar/XJarClassLoader.java
+++ b/src/main/java/io/xjar/jar/XJarClassLoader.java
@@ -2,7 +2,7 @@
import io.xjar.XDecryptor;
import io.xjar.XEncryptor;
-import io.xjar.XKit;
+import io.xjar.XTool;
import io.xjar.key.XKey;
import java.io.ByteArrayOutputStream;
@@ -64,7 +64,7 @@ protected Class> findClass(String name) throws ClassNotFoundException {
}
try (InputStream in = resource.openStream()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
- XKit.transfer(in, bos);
+ XTool.transfer(in, bos);
byte[] bytes = bos.toByteArray();
return defineClass(name, bytes, 0, bytes.length);
} catch (Throwable t) {
diff --git a/src/main/java/io/xjar/jar/XJarDecryptor.java b/src/main/java/io/xjar/jar/XJarDecryptor.java
index 0a5803c..d8a7485 100644
--- a/src/main/java/io/xjar/jar/XJarDecryptor.java
+++ b/src/main/java/io/xjar/jar/XJarDecryptor.java
@@ -6,7 +6,9 @@
import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.zip.Deflater;
@@ -17,36 +19,14 @@
* @author Payne 646742615@qq.com
* 2018/11/22 15:27
*/
-public class XJarDecryptor extends XEntryDecryptor implements XDecryptor, XConstants {
+public class XJarDecryptor extends XArchiveDecryptor implements XDecryptor, XConstants {
private final int level;
- public XJarDecryptor(XDecryptor xEncryptor) {
- this(xEncryptor, new XJarAllEntryFilter());
- }
-
- public XJarDecryptor(XDecryptor xDecryptor, XEntryFilter filter) {
- this(xDecryptor, Deflater.DEFLATED, filter);
- }
-
- public XJarDecryptor(XDecryptor xEncryptor, int level) {
- this(xEncryptor, level, new XJarAllEntryFilter());
- }
-
- public XJarDecryptor(XDecryptor xDecryptor, int level, XEntryFilter filter) {
+ public XJarDecryptor(XDecryptor xDecryptor, XEntryFilter filter, int level) {
super(xDecryptor, filter);
this.level = level;
}
- @Override
- public void decrypt(XKey key, File src, File dest) throws IOException {
- try (
- FileInputStream fis = new FileInputStream(src);
- FileOutputStream fos = new FileOutputStream(dest)
- ) {
- decrypt(key, fis, fos);
- }
- }
-
@Override
public void decrypt(XKey key, InputStream in, OutputStream out) throws IOException {
JarArchiveInputStream zis = null;
@@ -77,7 +57,6 @@ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
attributes.putValue("Main-Class", mainClass);
attributes.remove(new Attributes.Name("Jar-Main-Class"));
}
- XKit.removeKey(attributes);
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
@@ -89,7 +68,7 @@ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
boolean filtered = filtrate(entry);
XDecryptor decryptor = filtered ? xDecryptor : xNopDecryptor;
try (OutputStream eos = decryptor.decrypt(key, nos)) {
- XKit.transfer(nis, eos);
+ XTool.transfer(nis, eos);
}
}
zos.closeArchiveEntry();
@@ -97,9 +76,31 @@ public void decrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
zos.finish();
} finally {
- XKit.close(zis);
- XKit.close(zos);
+ XTool.close(zis);
+ XTool.close(zos);
}
}
+ public static XJarDecryptorBuilder builder() {
+ return new XJarDecryptorBuilder();
+ }
+
+ public static class XJarDecryptorBuilder extends XArchiveDecryptorBuilder {
+ private int level = Deflater.DEFLATED;
+
+ {
+ decryptor(new XSmtDecryptor());
+ filter(new XJarAllEntryFilter());
+ }
+
+ public XJarDecryptorBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ @Override
+ public XJarDecryptor build() {
+ return new XJarDecryptor(decryptor, filter, level);
+ }
+ }
}
diff --git a/src/main/java/io/xjar/jar/XJarEncryptor.java b/src/main/java/io/xjar/jar/XJarEncryptor.java
index c87075e..c78fb50 100644
--- a/src/main/java/io/xjar/jar/XJarEncryptor.java
+++ b/src/main/java/io/xjar/jar/XJarEncryptor.java
@@ -1,12 +1,18 @@
package io.xjar.jar;
import io.xjar.*;
+import io.xjar.compiler.XAwareCompiler;
+import io.xjar.digest.XJdkDigestFactory;
import io.xjar.key.XKey;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveInputStream;
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.NoSuchAlgorithmException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.Attributes;
@@ -19,44 +25,18 @@
* @author Payne 646742615@qq.com
* 2018/11/22 15:27
*/
-public class XJarEncryptor extends XEntryEncryptor implements XEncryptor, XConstants {
+public class XJarEncryptor extends XArchiveEncryptor implements XEncryptor, XConstants {
private final int level;
- private final int mode;
+ private final XDigestFactory digestFactory;
+ private final String digestAlgorithm;
+ private final XCompiler compiler;
- public XJarEncryptor(XEncryptor xEncryptor) {
- this(xEncryptor, new XJarAllEntryFilter());
- }
-
- public XJarEncryptor(XEncryptor xEncryptor, XEntryFilter filter) {
- this(xEncryptor, Deflater.DEFLATED, filter);
- }
-
- public XJarEncryptor(XEncryptor xEncryptor, int level) {
- this(xEncryptor, level, new XJarAllEntryFilter());
- }
-
- public XJarEncryptor(XEncryptor xEncryptor, int level, XEntryFilter filter) {
- this(xEncryptor, level, MODE_NORMAL, filter);
- }
-
- public XJarEncryptor(XEncryptor xEncryptor, int level, int mode) {
- this(xEncryptor, level, mode, new XJarAllEntryFilter());
- }
-
- public XJarEncryptor(XEncryptor xEncryptor, int level, int mode, XEntryFilter filter) {
+ public XJarEncryptor(XEncryptor xEncryptor, XEntryFilter filter, int level, XDigestFactory digestFactory, String digestAlgorithm, XCompiler compiler) {
super(xEncryptor, filter);
this.level = level;
- this.mode = mode;
- }
-
- @Override
- public void encrypt(XKey key, File src, File dest) throws IOException {
- try (
- FileInputStream fis = new FileInputStream(src);
- FileOutputStream fos = new FileOutputStream(dest)
- ) {
- encrypt(key, fis, fos);
- }
+ this.digestFactory = digestFactory;
+ this.digestAlgorithm = digestAlgorithm;
+ this.compiler = compiler;
}
@Override
@@ -64,9 +44,11 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
JarArchiveInputStream zis = null;
JarArchiveOutputStream zos = null;
Set indexes = new LinkedHashSet<>();
+ XDigest digest = null;
try {
+ digest = digestFactory.acquire(digestAlgorithm);
zis = new JarArchiveInputStream(in);
- zos = new JarArchiveOutputStream(out);
+ zos = new XDigestedOutputStream(out, digest);
zos.setLevel(level);
XUnclosedInputStream nis = new XUnclosedInputStream(zis);
XUnclosedOutputStream nos = new XUnclosedOutputStream(zos);
@@ -91,9 +73,6 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
attributes.putValue("Jar-Main-Class", mainClass);
attributes.putValue("Main-Class", "io.xjar.jar.XJarLauncher");
}
- if ((mode & FLAG_DANGER) == FLAG_DANGER) {
- XKit.retainKey(key, attributes);
- }
JarArchiveEntry jarArchiveEntry = new JarArchiveEntry(entry.getName());
jarArchiveEntry.setTime(entry.getTime());
zos.putArchiveEntry(jarArchiveEntry);
@@ -108,7 +87,7 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
}
XEncryptor encryptor = filtered ? xEncryptor : xNopEncryptor;
try (OutputStream eos = encryptor.encrypt(key, nos)) {
- XKit.transfer(nis, eos);
+ XTool.transfer(nis, eos);
}
}
zos.closeArchiveEntry();
@@ -132,14 +111,67 @@ public void encrypt(XKey key, InputStream in, OutputStream out) throws IOExcepti
String mainClass = manifest != null && manifest.getMainAttributes() != null ? manifest.getMainAttributes().getValue("Main-Class") : null;
if (mainClass != null) {
- XInjector.inject(zos);
+ XInjector.inject(zos, "io/xjar/**");
+ byte[] signature = digest.finish();
+ XSignature xSignature = new XSignature(digestAlgorithm, signature);
+ File lib = compiler.compile(key, xSignature);
+ JarArchiveEntry xLibEntry = new JarArchiveEntry("XJAR.SO");
+ xLibEntry.setTime(System.currentTimeMillis());
+ zos.putArchiveEntry(xLibEntry);
+ XTool.transfer(lib, zos);
+ zos.closeArchiveEntry();
}
zos.finish();
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e);
} finally {
- XKit.close(zis);
- XKit.close(zos);
+ XTool.close(zis);
+ XTool.close(zos);
+ if (digest != null) {
+ digestFactory.release(digestAlgorithm, digest);
+ }
}
}
+ public static XJarEncryptorBuilder builder() {
+ return new XJarEncryptorBuilder();
+ }
+
+ public static class XJarEncryptorBuilder extends XArchiveEncryptorBuilder {
+ private int level = Deflater.DEFLATED;
+ private XDigestFactory digestFactory = new XJdkDigestFactory();
+ private String digestAlgorithm = "MD5";
+ private XCompiler compiler = new XAwareCompiler();
+
+ {
+ encryptor(new XSmtEncryptor());
+ filter(new XJarAllEntryFilter());
+ }
+
+ public XJarEncryptorBuilder level(int level) {
+ this.level = level;
+ return this;
+ }
+
+ public XJarEncryptorBuilder digestFactory(XDigestFactory digestFactory) {
+ this.digestFactory = digestFactory;
+ return this;
+ }
+
+ public XJarEncryptorBuilder digestAlgorithm(String digestAlgorithm) {
+ this.digestAlgorithm = digestAlgorithm;
+ return this;
+ }
+
+ public XJarEncryptorBuilder compiler(XCompiler compiler) {
+ this.compiler = compiler;
+ return this;
+ }
+
+ @Override
+ public XJarEncryptor build() {
+ return new XJarEncryptor(encryptor, filter, level, digestFactory, digestAlgorithm, compiler);
+ }
+ }
}
diff --git a/src/main/java/io/xjar/key/XKey.java b/src/main/java/io/xjar/key/XKey.java
index 3e3601e..48f9260 100644
--- a/src/main/java/io/xjar/key/XKey.java
+++ b/src/main/java/io/xjar/key/XKey.java
@@ -1,12 +1,14 @@
package io.xjar.key;
+import io.xjar.XConstants;
+
/**
* 密钥
*
* @author 杨昌沛 646742615@qq.com
* 2018-11-22 14:54:10
*/
-public interface XKey {
+public interface XKey extends XConstants {
/**
* @return 密钥算法名称
diff --git a/src/main/java/io/xjar/zip/XZipDecryptor.java b/src/main/java/io/xjar/zip/XZipDecryptor.java
index f7c6200..1e41847 100644
--- a/src/main/java/io/xjar/zip/XZipDecryptor.java
+++ b/src/main/java/io/xjar/zip/XZipDecryptor.java
@@ -6,7 +6,9 @@
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.zip.Deflater;
/**
@@ -15,7 +17,7 @@
* @author Payne 646742615@qq.com
* 2018/11/22 15:27
*/
-public class XZipDecryptor extends XEntryDecryptor implements XDecryptor {
+public class XZipDecryptor extends XArchiveDecryptor implements XDecryptor {
private final int level;
public XZipDecryptor(XDecryptor xEncryptor) {
@@ -35,16 +37,6 @@ public XZipDecryptor(XDecryptor xDecryptor, int level, XEntryFilter implements XEncryptor {
+public class XZipEncryptor extends XArchiveEncryptor implements XEncryptor {
private final int level;
public XZipEncryptor(XEncryptor xEncryptor) {
@@ -35,16 +37,6 @@ public XZipEncryptor(XEncryptor xEncryptor, int level, XEntryFiltercount[0] = 0;
+ context->count[1] = 0;
+ context->state[0] = 0x67452301;//���ӱ�����ע�������ֽ���������ڴ�����С���ֽ���
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+}
+
+void MD5Update(MD5_CTX* context, unsigned char* input, unsigned int inputlen) {
+ unsigned int i = 0, index = 0, partlen = 0;
+ index = (context->count[0] >> 3) & 0x3F;//ģ64�ֽڵ���������һ�ε���Ϊ0
+ partlen = 64 - index;//��һ��partlenΪ64
+ //Ԥ����ǰ���64λ������ݳ���
+ context->count[0] += inputlen << 3;//�ı��ܵ�λ��,��32λ
+ if (context->count[0] < (inputlen << 3)) context->count[1]++;
+ context->count[1] += inputlen >> 29;//������3,���λ��,������32λ�������32λ
+
+ if (inputlen >= partlen) {
+ memcpy(&context->buffer[index], input, partlen);
+ MD5Transform(context->state, context->buffer);
+ //512λΪ1��
+ for (i = partlen; i + 64 <= inputlen; i += 64) MD5Transform(context->state, &input[i]);
+ index = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[index], &input[i], inputlen - i);//���ʣ�µ�һ����
+}
+
+//32λmd5
+void MD5Final(MD5_CTX* context, unsigned char digest[16]) {
+ unsigned int index = 0, padlen = 0;
+ unsigned char bits[8];
+ index = (context->count[0] >> 3) & 0x3F;//ģ64�ֽڵ�����
+ padlen = (index < 56) ? (56 - index) : (120 - index);//��Ҫ���ij��ȣ�ע�ⳤ��ռ8�ֽ�
+ MD5Encode(bits, context->count, 8);
+ MD5Update(context, PADDING, padlen);
+ MD5Update(context, bits, 8);//�������ʱ,index=0
+ MD5Encode(digest, context->state, 16);
+}
+
+void MD5Encode(unsigned char* output, unsigned int* input, unsigned int len) {
+ unsigned int i = 0, j = 0;//len��char�ij���
+ while (j < len) {
+ output[j] = input[i] & 0xFF;
+ output[j + 1] = (input[i] >> 8) & 0xFF;
+ output[j + 2] = (input[i] >> 16) & 0xFF;
+ output[j + 3] = (input[i] >> 24) & 0xFF;
+ i++;
+ j += 4;
+ }
+}
+
+void MD5Decode(unsigned int* output, unsigned char* input, unsigned int len) {
+ unsigned int i = 0, j = 0;
+ while (j < len) {
+ output[i] = (input[j]) |
+ (input[j + 1] << 8) |
+ (input[j + 2] << 16) |
+ (input[j + 3] << 24);
+ i++;
+ j += 4;
+ }
+}
+
+void MD5Transform(unsigned int state[4], unsigned char block[64]) {
+ unsigned int a = state[0];
+ unsigned int b = state[1];
+ unsigned int c = state[2];
+ unsigned int d = state[3];
+ unsigned int x[16];
+
+ MD5Decode(x, block, 64);
+ FF(a, b, c, d, x[0], 7, 0xd76aa478);//32���
+ FF(d, a, b, c, x[1], 12, 0xe8c7b756);
+ FF(c, d, a, b, x[2], 17, 0x242070db);
+ FF(b, c, d, a, x[3], 22, 0xc1bdceee);
+ FF(a, b, c, d, x[4], 7, 0xf57c0faf);
+ FF(d, a, b, c, x[5], 12, 0x4787c62a);
+ FF(c, d, a, b, x[6], 17, 0xa8304613);
+ FF(b, c, d, a, x[7], 22, 0xfd469501);
+ FF(a, b, c, d, x[8], 7, 0x698098d8);
+ FF(d, a, b, c, x[9], 12, 0x8b44f7af);
+ FF(c, d, a, b, x[10], 17, 0xffff5bb1);
+ FF(b, c, d, a, x[11], 22, 0x895cd7be);
+ FF(a, b, c, d, x[12], 7, 0x6b901122);
+ FF(d, a, b, c, x[13], 12, 0xfd987193);
+ FF(c, d, a, b, x[14], 17, 0xa679438e);
+ FF(b, c, d, a, x[15], 22, 0x49b40821);
+
+
+ GG(a, b, c, d, x[1], 5, 0xf61e2562);
+ GG(d, a, b, c, x[6], 9, 0xc040b340);
+ GG(c, d, a, b, x[11], 14, 0x265e5a51);
+ GG(b, c, d, a, x[0], 20, 0xe9b6c7aa);
+ GG(a, b, c, d, x[5], 5, 0xd62f105d);
+ GG(d, a, b, c, x[10], 9, 0x2441453);
+ GG(c, d, a, b, x[15], 14, 0xd8a1e681);
+ GG(b, c, d, a, x[4], 20, 0xe7d3fbc8);
+ GG(a, b, c, d, x[9], 5, 0x21e1cde6);
+ GG(d, a, b, c, x[14], 9, 0xc33707d6);
+ GG(c, d, a, b, x[3], 14, 0xf4d50d87);
+ GG(b, c, d, a, x[8], 20, 0x455a14ed);
+ GG(a, b, c, d, x[13], 5, 0xa9e3e905);
+ GG(d, a, b, c, x[2], 9, 0xfcefa3f8);
+ GG(c, d, a, b, x[7], 14, 0x676f02d9);
+ GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
+
+
+ HH(a, b, c, d, x[5], 4, 0xfffa3942);
+ HH(d, a, b, c, x[8], 11, 0x8771f681);
+ HH(c, d, a, b, x[11], 16, 0x6d9d6122);
+ HH(b, c, d, a, x[14], 23, 0xfde5380c);
+ HH(a, b, c, d, x[1], 4, 0xa4beea44);
+ HH(d, a, b, c, x[4], 11, 0x4bdecfa9);
+ HH(c, d, a, b, x[7], 16, 0xf6bb4b60);
+ HH(b, c, d, a, x[10], 23, 0xbebfbc70);
+ HH(a, b, c, d, x[13], 4, 0x289b7ec6);
+ HH(d, a, b, c, x[0], 11, 0xeaa127fa);
+ HH(c, d, a, b, x[3], 16, 0xd4ef3085);
+ HH(b, c, d, a, x[6], 23, 0x4881d05);
+ HH(a, b, c, d, x[9], 4, 0xd9d4d039);
+ HH(d, a, b, c, x[12], 11, 0xe6db99e5);
+ HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
+ HH(b, c, d, a, x[2], 23, 0xc4ac5665);
+
+
+ II(a, b, c, d, x[0], 6, 0xf4292244);
+ II(d, a, b, c, x[7], 10, 0x432aff97);
+ II(c, d, a, b, x[14], 15, 0xab9423a7);
+ II(b, c, d, a, x[5], 21, 0xfc93a039);
+ II(a, b, c, d, x[12], 6, 0x655b59c3);
+ II(d, a, b, c, x[3], 10, 0x8f0ccc92);
+ II(c, d, a, b, x[10], 15, 0xffeff47d);
+ II(b, c, d, a, x[1], 21, 0x85845dd1);
+ II(a, b, c, d, x[8], 6, 0x6fa87e4f);
+ II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
+ II(c, d, a, b, x[6], 15, 0xa3014314);
+ II(b, c, d, a, x[13], 21, 0x4e0811a1);
+ II(a, b, c, d, x[4], 6, 0xf7537e82);
+ II(d, a, b, c, x[11], 10, 0xbd3af235);
+ II(c, d, a, b, x[2], 15, 0x2ad7d2bb);
+ II(b, c, d, a, x[9], 21, 0xeb86d391);
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
\ No newline at end of file
diff --git a/src/main/resources/io/xjar/jni/MD5.h b/src/main/resources/io/xjar/jni/MD5.h
new file mode 100644
index 0000000..c026204
--- /dev/null
+++ b/src/main/resources/io/xjar/jni/MD5.h
@@ -0,0 +1,28 @@
+#include
+#include
+#include
+#include
+#include
+#include
+typedef struct {
+ unsigned int count[2];
+ unsigned int state[4];
+ unsigned char buffer[64];
+}MD5_CTX;
+
+#define F(x,y,z) ((x&y)|(~x&z))
+#define G(x,y,z) ((x&z)|(y&~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y^(x|~z))
+#define ROTATE_LEFT(x,n) ((x<>(32-n)))
+#define FF(a,b,c,d,x,s,ac) { a+=F(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
+#define GG(a,b,c,d,x,s,ac) { a+=G(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
+#define HH(a,b,c,d,x,s,ac) { a+=H(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
+#define II(a,b,c,d,x,s,ac) { a+=I(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
+
+void MD5Init(MD5_CTX* context);
+void MD5Update(MD5_CTX* context, unsigned char* input, unsigned int inputlen);
+void MD5Final(MD5_CTX* context, unsigned char digest[16]);
+void MD5Transform(unsigned int state[4], unsigned char block[64]);
+void MD5Encode(unsigned char* output, unsigned int* input, unsigned int len);
+void MD5Decode(unsigned int* output, unsigned char* input, unsigned int len);
\ No newline at end of file
diff --git a/src/main/resources/io/xjar/jni/XJni.cpp b/src/main/resources/io/xjar/jni/XJni.cpp
new file mode 100644
index 0000000..f1d7f99
--- /dev/null
+++ b/src/main/resources/io/xjar/jni/XJni.cpp
@@ -0,0 +1,43 @@
+#include "XJni.h"
+
+JNIEXPORT jobject JNICALL Java_io_xjar_XJni_call(JNIEnv* env, jobject thiz)
+{
+ const char* algorithm = "${xKey.algorithm}";
+ jint keysize = ${xKey.keysize};
+ jint ivsize = ${xKey.ivsize};
+ const char* password = "";
+ const jbyte secretKey[] = { <%
+ for (k in xKey.secretKey) {
+ print(k);
+ if (!kLP.last) {
+ print(', ');
+ }
+ }
+ %> };
+ jbyteArray key = env->NewByteArray(sizeof(secretKey) / sizeof(secretKey[0]));
+ env->SetByteArrayRegion(key, 0, sizeof(secretKey) / sizeof(secretKey[0]), secretKey);
+
+ const jbyte ivParameter[] = { <%
+ for (k in xKey.ivParameter) {
+ print(k);
+ if (!kLP.last) {
+ print(', ');
+ }
+ }
+ %> };
+ jbyteArray iv = env->NewByteArray(sizeof(ivParameter) / sizeof(ivParameter[0]));
+ env->SetByteArrayRegion(iv, 0, sizeof(ivParameter) / sizeof(ivParameter[0]), ivParameter);
+
+ jclass keyClass = env->FindClass("io/xjar/key/XSymmetricSecureKey");
+ jmethodID constructor = env->GetMethodID(keyClass, "", "(Ljava/lang/String;IILjava/lang/String;[B[B)V");
+ return env->NewObject(
+ keyClass,
+ constructor,
+ env->NewStringUTF(algorithm),
+ keysize,
+ ivsize,
+ env->NewStringUTF(password),
+ key,
+ iv
+ );
+}
\ No newline at end of file
diff --git a/src/main/resources/io/xjar/jni/XJni.h b/src/main/resources/io/xjar/jni/XJni.h
new file mode 100644
index 0000000..0154cca
--- /dev/null
+++ b/src/main/resources/io/xjar/jni/XJni.h
@@ -0,0 +1,20 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include "jni.h"
+/* Header for class io_xjar_XJni */
+
+#ifndef _Included_io_xjar_XJni
+#define _Included_io_xjar_XJni
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: io_xjar_XJni
+ * Method: call
+ * Signature: ()[B
+ */
+JNIEXPORT jobject JNICALL Java_io_xjar_XJni_call(JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/test/java/test/io/xjar/XJarTest.java b/src/test/java/test/io/xjar/XJarTest.java
new file mode 100644
index 0000000..e0c1b8e
--- /dev/null
+++ b/src/test/java/test/io/xjar/XJarTest.java
@@ -0,0 +1,31 @@
+package test.io.xjar;
+
+import org.beetl.core.Configuration;
+import org.beetl.core.GroupTemplate;
+import org.beetl.core.Template;
+import org.beetl.core.resource.ClasspathResourceLoader;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * @author Payne 646742615@qq.com
+ * 2019/7/4 16:24
+ */
+public class XJarTest {
+
+ @Test
+ public void test() throws IOException {
+ //初始化代码
+ ClasspathResourceLoader resourceLoader = new ClasspathResourceLoader();
+ Configuration cfg = Configuration.defaultConfiguration();
+ GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
+ //获取模板
+ Template t = gt.getTemplate("io/xjar/jni/XJni.cpp");
+ t.binding("key", new byte[]{1, 2, 3, 4});
+ //渲染结果
+ String str = t.render();
+ System.out.println(str);
+ }
+
+}