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
    

      

    剩下的你懂的哦~

    请一键三连···

  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/-flq/p/14297274.html
Copyright © 2011-2022 走看看