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> filters) { + public static XAllEntryFilter all(Collection> filters) { return new XAllEntryFilter<>(filters); } @@ -300,7 +104,7 @@ public static XAllEntryFilter all(Collection> 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> filters) { + public static XAllEntryFilter and(Collection> filters) { return new XAllEntryFilter<>(filters); } @@ -319,7 +123,7 @@ public static XAllEntryFilter and(Collection> 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> filters) { + public static XAnyEntryFilter any(Collection> filters) { return new XAnyEntryFilter<>(filters); } @@ -338,7 +142,7 @@ public static XAnyEntryFilter any(Collection> 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> filters) { + public static XAnyEntryFilter or(Collection> filters) { return new XAnyEntryFilter<>(filters); } @@ -356,36 +160,30 @@ public static XAnyEntryFilter or(Collection> 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); + } + +}