前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

通过类加载器实现java项目的加密(使用类加载器读取配置文件)

qiguaw 2024-10-01 14:52:16 资源文章 13 ℃ 0 评论

场景:项目需要部署在客户的服务器,但是又不想暴露源代码。

方案步骤:

  1. 使用idea编号好代码后,通过自动编译成class文件,即可获取到核心的class文件;
  2. 使用加密工具类,读取核心class文件,对class文件进行加密处理,如示例在字节码的尾部加入java字节码;
  3. 自定义类加载器MyClassLoader集成自ClassLoader, 在重载findClass方法中通过io读取字节码文件,判断尾部后去掉java字节码;
  4. 项目启动后,调用MyClassLoader完成对加密模块的加载即可。
import java.io.*;
/**
 * @Description: 自定义类加载器实现java字节码的加解密
 */
public class MyClassLoader extends ClassLoader{

    private String key = "java";

    private String codePath;
    public MyClassLoader(ClassLoader parent, String codePath) {
        super(parent); this.codePath = codePath;
    }

    public MyClassLoader(String codePath) { this.codePath = codePath; }


    /**
     * 字节码加密
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
    public void writeKey(String name){
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.字节码路径
            String fileName = codePath + name + ".class";
            //2.获取输入流
            bis = new BufferedInputStream(new FileInputStream(fileName));
            //3.获取输出流
            baos = new ByteArrayOutputStream();
            //4.io读写
            int len;
            byte[] data = new byte[1024];
            while ((len = bis.read(data)) != -1) {
                baos.write(data, 0, len);
            }
            baos.write(key.getBytes(),0,key.length());
            baos.writeTo(new FileOutputStream(fileName));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected Class<?> findClass(String name)  {
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.字节码路径
            String fileName = codePath + name + ".class";
            //2.获取输入流
            bis = new BufferedInputStream(new FileInputStream(fileName));
            //3.获取输出流
            baos = new ByteArrayOutputStream();
            //4.io读写
            int len;
            byte[] data = new byte[1024];
            while ((len = bis.read(data)) != -1) {
                if( len < 1024 ){
                    //快结束了, 取消加密串
                    baos.write(data, 0, len - key.getBytes().length);
                }else{
                    baos.write(data, 0, len);
                }

            }
            //5.获取内存中字节数组
            byte[] byteCode = baos.toByteArray();
            //6.调用defineClass 将字节数组转成Class对象
            Class<?> defineClass = defineClass(null, byteCode, 0, byteCode.length);
            return defineClass;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static void main(String[] args) {

        MyClassLoader classLoader = new MyClassLoader("f:/");
        //classLoader.writeKey("TestMain2");
        try {
            Class<?> clazz = classLoader.loadClass("TestMain");
            System.out.println("我是由"+clazz.getClassLoader().getClass().getName()+"类加载器加载 的");

            System.out.println( clazz.newInstance() );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表