zoukankan      html  css  js  c++  java
  • 使用Xjar对jar文件进行加密,防止反编译

    软件简介

    XJar — Spring-Boot JAR 包加密运行工具,避免源码泄露以及反编译。

    Spring Boot JAR安全加密运行工具,同时支持原生的JAR。

    基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或反编译。

    功能特性

    • 无需侵入代码,只需要把编译好的JAR包通过工具加密即可。

    • 完全内存解密,杜绝源码以及字节码泄露以及反编译。

    • 支持所有JDK内置加解密算法。

    • 可选择需要加解密的字节码或其他资源文件,避免计算资源浪费。

    环境依赖-废话不多说,直接上源码。新建项目

    配置pom

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com</groupId>
        <artifactId>xjar-encrype</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <!-- 设置 jitpack.io 仓库 -->
        <repositories>
            <repository>
                <id>jitpack.io</id>
                <url>https://jitpack.io</url>
            </repository>
        </repositories>
    
        <!-- 添加 XJar 依赖 -->
        <dependencies>
            <dependency>
                <groupId>com.github.core-lib</groupId>
                <artifactId>xjar</artifactId>
                <version>v2.0.6</version>
            </dependency>
        </dependencies>
    
    
    </project>
    

      写代码

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import static io.xjar.agent.hibernate.XjarTest.encryptJarDangerMode;
    
    public class UserSwing {
    
        public static void main(String[] args) {
            // 创建 JFrame 实例
            JFrame frame = new JFrame("Jar加密,防止反编译");
            // Setting the width and height of frame
            frame.setSize(600, 400);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            /* 创建面板,这个类似于 HTML 的 div 标签
             * 我们可以创建多个面板并在 JFrame 中指定位置
             * 面板中我们可以添加文本字段,按钮及其他组件。
             */
            JPanel panel = new JPanel();
            // 添加面板
            frame.add(panel);
            /*
             * 调用用户定义的方法并添加组件到面板
             */
            placeComponents(panel);
    
            // 设置界面可见
            frame.setVisible(true);
        }
    
        private static void placeComponents(final JPanel panel) {
    
            /* 布局部分我们这边不多做介绍
             * 这边设置布局为 null
             */
            panel.setLayout(null);
    
            // 创建 需要加密的jar JLabel
            JLabel fromLabel = new JLabel("选择需要加密的jar:");
            fromLabel.setBounds(10,20,120,25);
            panel.add(fromLabel);
    
            /*
             * 用于记录未加密jar的文本域
             */
            final JTextField fromText = new JTextField(20);
            fromText.setBounds(140,20,210,25);
            panel.add(fromText);
    
            // 创建选择按钮
            JButton fromButton = new JButton("选择...");
            fromButton.setBounds(360, 20, 80, 25);
            panel.add(fromButton);
    
    
            // 加密后jar要保存的位置
            JLabel toLabel = new JLabel("选择需要保存的位置");
            toLabel.setBounds(10,50,120,25);
            panel.add(toLabel);
    
            /*
             *文本域用于记录保存路径
             */
            final JTextField toText = new JTextField(20);
            toText.setBounds(140,50,210,25);
            panel.add(toText);
    
            // 创建选择按钮
            JButton toButton = new JButton("选择...");
            toButton.setBounds(360, 50, 80, 25);
            panel.add(toButton);
    
    
            // 输入密码的文本域
            JLabel passwordLabel = new JLabel("加密密码:");
            passwordLabel.setBounds(10,80,80,25);
            panel.add(passwordLabel);
    
            /*
             * 这个类似用于输入的文本域
             * 但是输入的信息会以点号代替,用于包含密码的安全性
             */
            final JPasswordField passwordText = new JPasswordField(20);
            passwordText.setBounds(100,80,165,25);
            panel.add(passwordText);
    
            // 创建登录按钮
            JButton startButton = new JButton("开始");
            startButton.setBounds(10, 110, 80, 25);
            panel.add(startButton);
    
            //日志显示框
            final JTextArea textArea = new JTextArea("");
            textArea.setBounds(10,150,300,150);
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            panel.add(textArea);
    
            /*
             * 选择jar按钮监听事件
             */
            fromButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {  //按钮点击事件
                    JFileChooser chooser = new JFileChooser();             //设置选择器
                    chooser.setMultiSelectionEnabled(false);             //设为单选
                    int returnVal = chooser.showOpenDialog(null);        //是否打开文件选择框
                    if (returnVal == JFileChooser.APPROVE_OPTION) {          //如果符合文件类型
                        String filepath = chooser.getSelectedFile().getAbsolutePath();      //获取绝对路径
                        if (!".jar".equals(filepath.substring(filepath.length()-4))) {
                            JOptionPane.showMessageDialog(null, "文件格式不正确,请选择jar文件!", "文件格式错误", JOptionPane.ERROR_MESSAGE);
                        } else {
                            fromText.setText(filepath);
                        }
                        System.out.println(filepath);
                    }
                }
            });
    
            /*
             * 选择加密后jar保存路径按钮监听事件
             */
            toButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {  //按钮点击事件
                    JFileChooser chooser = new JFileChooser();             //设置选择器
                    chooser.setMultiSelectionEnabled(false);             //设为单选
                    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); //设置只选目录
                    chooser.setDialogTitle("选择加密后jar保存位置");
                    int returnVal = chooser.showOpenDialog(null);        //是否打开文件选择框
                    if (returnVal == JFileChooser.APPROVE_OPTION) {          //如果符合文件类型
                        String filepath = chooser.getSelectedFile().getAbsolutePath();      //获取绝对路径
                        toText.setText(filepath);
                        System.out.println(filepath);
                    }
                }
            });
    
            /*
             * 选择开始径按钮的监听事件
             */
            startButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    String fromJarPath = fromText.getText();
                    String toJarPath = toText.getText() + "\encrypt" + getNowDateTime() + ".jar";
                    String password = new String(passwordText.getPassword());
                    System.out.println("fromJarPath=" + fromJarPath);
                    System.out.println("toJarPath=" + toJarPath);
                    System.out.println("password=" + password);
                    if (fromJarPath != null && !"".equals(fromJarPath)) {
                        if (toJarPath != null && !"\encrypt".equals(toJarPath.substring(0,8))) {
                            if (password != null && !"".equals(password)) {
                                //打印输入日志
                                StringBuilder builder = new StringBuilder();
                                builder.append("fromJarPath=" + fromJarPath + "
    ")
                                        .append("toJarPath=" + toJarPath + "
    ") ;
                                textArea.setText(builder.toString());
                                //开始加密文件
                                encryptJarDangerMode(fromJarPath,toJarPath,password);
                                textArea.append("jar加密成功!
    请测试接口是否正常(注意:Swagger不可用)");
                            } else {
                                JOptionPane.showMessageDialog(null, "请输入加密的密码!", "密码不能为空!", JOptionPane.ERROR_MESSAGE);
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "保存路径不能为空!", "保存路径不能为空!", JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "jar文件不能为空!", "jar文件不能为空!", JOptionPane.ERROR_MESSAGE);
                    }
    
                }
            });
        }
    
        /**
         * 获取当前格式化时间的方法
         * @return
         */
        private static String getNowDateTime() {
            String dateNow = "";
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = new Date();
            dateNow = format.format(date);
            return dateNow;
        }
    }
    

      直接将项目main运行 如下图

     当然还有直接了当的方法哦

    import io.xjar.XConstants;
    import io.xjar.XKit;
    import io.xjar.boot.XBoot;
    import io.xjar.key.XKey;
    
    /**
     * @description jar包加密
     * jar加密后,大小会翻倍,同时swagger无法访问,接口暂时未发现问题
     */
    public class XjarTest {
    
        public static void main(String[] args) {
            // Spring-Boot Jar包加密
            String password = "adas";
            String fromJarPath = "F:\old-0.0.1-SNAPSHOT.jar";
            String toJarPath = "F:\new.jar";
            encryptJarDangerMode(fromJarPath, toJarPath, password);
        }
    
        /**
         * jar包加密,防止反编译
         * 此编译方式在运行jar包时需要输入密码
         * 运行方式一 :
         *      // 命令行运行JAR 然后在提示输入密码的时候输入密码后按回车即可正常启动
         *      java -jar /path/to/encrypted.jar
         * 运行方式二:
         *      // 也可以通过传参的方式直接启动,不太推荐这种方式,因为泄露的可能性更大!
         *      java -jar /path/to/encrypted.jar --xjar.password=PASSWORD
         * 运行方式三:
         *      // 对于 nohup 或 javaw 这种后台启动方式,无法使用控制台来输入密码,推荐使用指定密钥文件的方式启动
         *      nohup java -jar /path/to/encrypted.jar --xjar.keyfile=/path/to/xjar.key
         *      xjar.key 文件说明:
         *      格式:
         *          password: PASSWORD
         *          algorithm: ALGORITHM
         *          keysize: KEYSIZE
         *          ivsize: IVSIZE
         *          hold: HOLD
         *      参数说明:
         *          password 	密码 	无 	密码字符串
         *          algorithm 	密钥算法 	AES 	支持JDK所有内置算法,如AES / DES ...
         *          keysize 	密钥长度 	128 	根据不同的算法选取不同的密钥长度。
         *          ivsize 	向量长度 	128 	根据不同的算法选取不同的向量长度。
         *          hold 	是否保留 	false 	读取后是否保留密钥文件。
         * @param fromJarPath 需要加密的jar
         * @param toJarPath 加密后的jar
         * @param password 加密密码
         */
        public static void encryptJar(String fromJarPath, String toJarPath, String password) {
    
            try {
                // Spring-Boot Jar包加密
                XKey xKey = XKit.key(password);
                XBoot.encrypt(fromJarPath, toJarPath, xKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * jar包解密
         * @param fromJarPath 已通过Xjar加密的jar文件路径
         * @param toJarPath 解密后的jar文件
         * @param password 密码
         */
        public static void decryptJar(String fromJarPath, String toJarPath, String password) {
            try {
                XKey xKey = XKit.key(password);
                XBoot.decrypt(fromJarPath, toJarPath, xKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * jar包危险加密模式
         * 即不需要输入密码即可启动的加密方式,这种方式META-INF/MANIFEST.MF中会保留密钥,请谨慎使用!
         * @param fromJarPath 需要加密的jar
         * @param toJarPath 加密后的jar
         * @param password 加密密码
         */
        public static void encryptJarDangerMode(String fromJarPath, String toJarPath, String password) {
            try {
                XKey xKey = XKit.key(password);
                XBoot.encrypt(fromJarPath, toJarPath, xKey, XConstants.MODE_DANGER);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    

      jar包下载不下来可配置maven私服

          <mirror>
              <id>alimaven</id>
              <mirrorOf>central,!jitpack.io</mirrorOf>
              <name>aliyun maven</name>
              <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
          </mirror>
    

      一个命令解决maven依赖下载失败后无法重新下载依赖的问题-请到本地maven下执行该cmd命令

    for /r %i in (*.lastUpdated) do del %i
    

      

    剩下的你懂的哦~

    请一键三连···

  • 相关阅读:
    腰围2尺1,2,3,4,5,6,7,8寸各自等于是多少厘米/英寸(对比表)
    MySQL Server 5.0 下载与 安装指南[图文] (安装到非系统路径+设置root账号相应password)
    UISearchDisplayController UISearchBar
    第八届蓝桥杯JavaB组省赛真题
    第八届蓝桥杯JavaA组省赛真题
    第八届蓝桥杯JavaA组省赛真题
    第八届蓝桥杯JavaA组省赛真题
    第八届蓝桥杯JavaA组省赛真题
    第八届蓝桥杯JavaA组省赛真题
    第七届蓝桥杯JavaC组省赛真题
  • 原文地址:https://www.cnblogs.com/-flq/p/14297274.html
Copyright © 2011-2022 走看看