类加载器的加密解密

模拟一个简单的字符串加密工具类

原理:

异或^的使用:

int i;

byte m;

i ^ m ^ m == i;//true

package com.dwz.classLoader.chapter3;

public class SimpleEncrypt {
    private final static String plain = "Hello ClassLoader";
    private final static byte ENCRYPT_FACTOR = (byte) 0xff;
    
    public static void main(String[] args) {
        byte[] bytes = plain.getBytes();
        byte[] encrypt = new byte[bytes.length];
        for(int i = 0; i < bytes.length; i++) {
            //异或
            encrypt[i] = (byte) (bytes[i] ^ ENCRYPT_FACTOR);
        }
        System.out.println(new String(encrypt));
        
        byte[] decrypt = new byte[encrypt.length];
        for(int i = 0; i < encrypt.length; i++) {
            //异或
            decrypt[i] = (byte) (encrypt[i] ^ ENCRYPT_FACTOR);
        }
    }
}

创建文件加密解密的工具类

package com.dwz.classLoader.chapter3;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public final class EncryptUtils {
    public final static byte ENCRYPT_FACTOR = (byte) 0xff;

    private EncryptUtils() {
        //empty
    }
    
    public static void doEncrypt(String source, String target) {
        try(FileInputStream fis = new FileInputStream(source);
            FileOutputStream fos = new FileOutputStream(target)) {
            
            int data;
            while((data = fis.read()) != -1) {
                fos.write(data ^ ENCRYPT_FACTOR);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        doEncrypt("C:/Users/Administrator/Desktop/classloader1/com/dwz/classLoader/chapter2/MyObject.class", "C:/Users/Administrator/Desktop/classloader1/com/dwz/classLoader/chapter2/MyObject.class1");
    }
}
doEncrypt(String source, String target)执行一次是加密,两次是解密
带加密的类加载器
package com.dwz.classLoader.chapter3;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

public class EncryptClassLoader extends ClassLoader {
    private final static String DEFAULT_DIR = "C:/Users/Administrator/Desktop/classloader1";
    
    private String dir = DEFAULT_DIR;
    
    public EncryptClassLoader() {
        super();
    }
    
    public EncryptClassLoader(ClassLoader parent) {
        super(parent);
    }
    
    public void setDir(String dir) {
        this.dir = dir;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String classPath = name.replaceAll("\.", "/");
        File classFile = new File(dir, classPath + ".class");
        
        if(!classFile.exists()) {
            throw new ClassNotFoundException("The class " + name + " not found under dictory [" + dir + "]") ;
        }
        
        byte[] classBytes = loadClassBytes(classFile);
        if(null == classBytes || classBytes.length == 0) {
            throw new ClassNotFoundException("load the class " + name + " failed");
        }
        return this.defineClass(name, classBytes, 0, classBytes.length);
    }

    private byte[] loadClassBytes(File classFile) {
        try(ByteArrayOutputStream baos = new ByteArrayOutputStream();
                FileInputStream fis = new FileInputStream(classFile)) {
            int data;
            while((data = fis.read()) != -1) {
                baos.write(data ^ EncryptUtils.ENCRYPT_FACTOR);
            }
            baos.flush();
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
}

测试:

package com.dwz.classLoader.chapter3;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.dwz.classLoader.chapter2.MyClassLoader;

public class ClassLoaderTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        EncryptClassLoader classLoader1 = new EncryptClassLoader();
        Class<?> loadClass = classLoader1.loadClass("com.dwz.classLoader.chapter2.MyObject");
        System.out.println(loadClass);
        System.out.println(loadClass.getClassLoader());
        
        Object obj = loadClass.newInstance();
        Method method = loadClass.getMethod("hello", new Class<?>[] {});
        Object result = method.invoke(obj, new Object[] {});
        System.out.println(result);
    }
}

测试步骤:

1.先复制编译好的MyObject.class用EncryptUtils.doEncrypt(String source, String target);加密复制到类加载器指定文件 DEFAULT_DIR 中

2.删除编译好的MyObject.class文件

3.执行测试main

参考文章:

byte数组与java基本对象的转换以及异或^的理解

原文地址:https://www.cnblogs.com/zheaven/p/12202483.html