对jar或者war进行加密解密
whycxzp
2021-12-22 f6b935781bcb43faea7aa894ce3a55873769efb3
1.内置密码解码,多重密码混淆
2.外部运行虚假密码(未生效密码混淆)
5个文件已修改
82 ■■■■■ 已修改文件
beale-core/src/main/java/com/whyc/Const.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
beale-core/src/main/java/com/whyc/CoreAgent.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
beale-core/src/main/java/com/whyc/JarDecryptor.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
beale-core/src/main/java/com/whyc/JarEncryptor.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
beale-core/src/main/java/com/whyc/util/EncryptUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
beale-core/src/main/java/com/whyc/Const.java
@@ -10,6 +10,13 @@
    //加密出来的文件名
    public static final String FILE_NAME = ".classes";
    //密码文件
    public static final String FILE_NAME2 = "launch_imp.dll";
    //密码
    public static final String FILE_NAME2_DESCRIPTION = "active code";
    //AES 16为key
    public static final String AES_KEY="wuhanyuanchangco";
    //lib下的jar解压的目录名后缀
    public static final String LIB_JAR_DIR = "__temp__";
beale-core/src/main/java/com/whyc/CoreAgent.java
@@ -6,6 +6,7 @@
import java.io.Console;
import java.io.File;
import java.lang.instrument.Instrumentation;
import java.nio.charset.Charset;
/**
@@ -32,7 +33,8 @@
        char[] pwd;
        //读取jar隐藏的密码,无密码启动模式(jar)
        pwd = JarDecryptor.readPassFromJar(new File(JarUtils.getRootPath(null)));
        //pwd = JarDecryptor.readPassFromJar(new File(JarUtils.getRootPath(null)));
        pwd = JarDecryptor.readPassFromJar2(new File(JarUtils.getRootPath(null)));
        if (args != null) {
            options.parse(args.split(" "));
@@ -94,15 +96,22 @@
        }
        //验证密码,jar包是才验证
        byte[] passHash = JarDecryptor.readEncryptedFile(new File(JarUtils.getRootPath(null)), Const.CONFIG_PASSHASH);
        /*System.out.println("验证jar,密码路径"+JarUtils.getRootPath(null));
        byte[] passHash = JarDecryptor.readEncryptedFile2(new File(JarUtils.getRootPath(null)),Const.FILE_NAME2);
        if (passHash != null) {
            char[] p1 = StrUtils.toChars(passHash);
            char[] p1 = StrUtils.merger(pwd, EncryptUtils.SALT);
            char[] p2 = EncryptUtils.md5(StrUtils.merger(pwd, EncryptUtils.SALT));
            p2 = EncryptUtils.md5(StrUtils.merger(EncryptUtils.SALT, p2));
            if (!StrUtils.equal(p1, p2)) {
                Log.println("\nERROR: Startup failed, invalid password.\n");
                System.exit(0);
            }
        }*/
        byte[] pwdHash = JarDecryptor.readEncryptedFile2(new File(JarUtils.getRootPath(null)),Const.FILE_NAME2);
        if (pwdHash != null) {
            String pwdTrue = EncryptUtils.deAES(new String(pwdHash, Charset.forName("utf-8")), Const.AES_KEY.toCharArray());
            pwdTrue = pwdTrue.replace(" ","").replace(",","").replace("[","").replace("]","");
            pwd = pwdTrue.toCharArray();
        }
        //GO
@@ -162,4 +171,8 @@
        }
        return pwd;
    }
    public static void main(String[] args) {
        char[] chars = JarDecryptor.readPassFromJar(new File(JarUtils.getRootPath(null)));
    }
}
beale-core/src/main/java/com/whyc/JarDecryptor.java
@@ -21,6 +21,9 @@
    //加密后文件存放位置
    private static final String ENCRYPT_PATH = "META-INF/" + Const.FILE_NAME + "/";
    //加密后文件存放位置
    private static final String DESCRIPTION_PATH = "META-INF/";
    /**
     * 单例
     *
@@ -106,6 +109,28 @@
    }
    /**
     * 在jar文件或目录中读取密码字节
     *
     * @param workDir jar文件或目录
     * @param name    文件名
     * @return 文件字节数组
     */
    public static byte[] readEncryptedFile2(File workDir, String name) {
        byte[] bytes = null;
        String fileName = DESCRIPTION_PATH + name;
        //jar文件
        if (workDir.isFile()) {
            bytes = JarUtils.getFileFromJar(workDir, fileName);
        } else {//war解压的目录
            File file = new File(workDir, fileName);
            if (file.exists()) {
                bytes = IoUtils.readFileToByte(file);
            }
        }
        return bytes;
    }
    /**
     * 读取隐藏在jar的密码
     *
     * @param workDir jar路径
@@ -121,6 +146,21 @@
    }
    /**
     * 读取隐藏在jar的密码
     *
     * @param workDir jar路径
     * @return 密码char
     */
    public static char[] readPassFromJar2(File workDir) {
        byte[] passbyte = readEncryptedFile2(workDir, Const.FILE_NAME2);
        if (passbyte != null) {
            char[] pass = StrUtils.toChars(passbyte);
            return EncryptUtils.md5(pass);
        }
        return null;
    }
    /**
     * 解密配置文件,spring读取文件时调用
     *
     * @param path 配置文件路径
beale-core/src/main/java/com/whyc/JarEncryptor.java
@@ -192,16 +192,28 @@
        //加密后存储的位置
        File metaDir = new File(this.targetDir, "META-INF" + File.separator + Const.FILE_NAME);
        File descriptionDir = new File(this.targetDir, "META-INF" + File.separator);
        if (!metaDir.exists()) {
            metaDir.mkdirs();
        }
        //无密码模式,自动生成一个密码
        if (this.password.length == 1 && this.password[0] == '#') {
        /*if (this.password.length == 1 && this.password[0] == '#') {
            char[] randChars = EncryptUtils.randChar(32);
            this.password = EncryptUtils.md5(randChars);
            File configPass = new File(metaDir, Const.CONFIG_PASS);
            IoUtils.writeFile(configPass, StrUtils.toBytes(randChars));
        }*/
        //密码文件生成
        if (this.password.length == 1 && this.password[0] == '#') {
            char[] randChars2 = Const.FILE_NAME2_DESCRIPTION.replace(" ", "").toCharArray();
            //密码为混淆 原码+盐
            this.password = StrUtils.merger(randChars2, EncryptUtils.SALT);
            String password2 = EncryptUtils.enAES(Arrays.toString(password), Const.AES_KEY.toCharArray());
            File configPass = new File(descriptionDir, Const.FILE_NAME2);
            //将混淆后的密码加密后存储
            IoUtils.writeFile(configPass, password2.getBytes());
        }
        //有机器码
beale-core/src/main/java/com/whyc/util/EncryptUtils.java
@@ -17,7 +17,7 @@
 */
public class EncryptUtils {
    //盐
    public static final char[] SALT = {'w', 'h', 'o', 'i', 's', 'y', 'o', 'u', 'r', 'd', 'a', 'd', 'd', 'y', '#', '$', '@', '#', '@'};
    public static final char[] SALT = {'i', 's', 'a', 'o', 'f', 'f', 'i', 'c', 'a', 'l', 'p', 'r', 'o', 'j','e','c','t', '#', '$', '@', '#', '@'};
    //rsa 长度
    private static int KEY_LENGTH = 1024;