内省,类的加密和自定义加载器

反射:内省的使用(避免一直使用暴力反射)

//通过内省技术:给一个字段的名字和字节码文件对象就可以得到关于该字段的设置和读取方法
public class ReflectDemo {

	public static void main(String[] args) throws Exception {
//		new Test().setAge(-10);
		Class clazz = Class.forName("com.practice922.Test");
		Field field = clazz.getDeclaredField("age");
		Object obj = clazz.newInstance();
		field.setAccessible(true);
		field.set(obj, -1);
		System.out.println(obj);
	}

}
class Test{
	private int age;

	public int getAge() {
		return age;
	}

	public void setAge(int age) throws AgeException {
		if(age<0||age>260){
			throw new AgeException();
		}
		this.age = age;
	}
	

	@Override
	public String toString() {
		return "Test [age=" + age + "]";
	}
	
}

自定义的Exception

public class AgeException extends Exception {
	@Override
	public String getMessage() {
		return "年龄输入错误";
	}
	}

此时暴力反射强行写入,不会报错,不能使用。

 

 

 

内省

public static void main(String[] args) throws Exception {
//		new Test().setAge(-10);
		Class clazz = Class.forName("com.practice922.Test");
//		Field field = clazz.getDeclaredField("age");
		Object obj = clazz.newInstance();
//		field.setAccessible(true);
//		field.set(obj, -1);
//		System.out.println(obj);
		PropertyDescriptor pd = new PropertyDescriptor("age", clazz);
//		获取用于写入属性值的方法
		Method writeMethod = pd.getWriteMethod();
		writeMethod.invoke(obj, 18);
//		获取用于读属性值的方法
		Method readMethod = pd.getReadMethod();
		Object age = readMethod.invoke(obj, null);
		System.out.println(age);
		System.out.println(obj);
		
	}

}

 

PropertyDescriptor pd = new PropertyDescriptor("age", clazz, "getage", "setage");直接获取读取属性值的方法

 

自定义类加载器(类的加密和用自己的加载器进行加载)

public class MyClassLoaderDemo {

	public static void main(String[] args) throws Exception {
		Person p = new Person();
		System.out.println(p);

		// 一个数异或一个数值两次,值是本身
		// int a = 10;
		// System.out.println(a = a ^ 89);
		// System.out.println(a = a ^ 89);
		byte[] bytes = XORClass("/Users/yoofale/Documents/JAVASEworkspace/Practice/bin/com/practice922/Person.class");
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		int len;
		byte[] buf = new byte[1024];
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(
				"/Users/yoofale/Documents/JAVASEworkspace/Practice/bin/com/practice922/Person.class"));
		while ((len = bais.read()) != -1) {
			bos.write(buf, 0, len);
			bos.flush();
		}
		bos.close();
		System.out.println("加密成功");
	}

	/**
	 * 
	 * 加密或者解密字节码文件
	 * 
	 * @param classPath
	 * @return 加密或者解密之后的文件数组
	 * @throws Exception
	 */
	public static byte[] XORClass(String classPath) throws Exception {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classPath));
		byte[] buf = new byte[1024];
		int len;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while ((len = bis.read(buf)) != -1) {
			baos.write(buf, 0, len);
			baos.flush();
		}
		byte[] byteArray = baos.toByteArray();
		// 将所有字节都异或成一个值,实现加密
		for (int i = 0; i < byteArray.length; i++) {
			byte b = byteArray[i];
			byteArray[i] = (byte) (b ^ 32);
		}
		bis.close();
		return byteArray;
	}
}

 

 

 

自定义的加载器

public class MyClassLoder extends ClassLoader {
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		try {
			// TODO Auto-generated method stub
			byte[] bytes = ClassUtils.XORClass(name);
			return defineClass(null, bytes, 0, bytes.length);
		} catch (ClassFormatError | Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
}

 

 

 

封装的加密

public class ClassUtils {
	/**
	 * 
	 * 加密或者解密字节码文件
	 * 
	 * @param classPath
	 * @return 加密或者解密之后的文件数组
	 * @throws Exception
	 */
	public static byte[] XORClass(String classPath) throws Exception {
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classPath));
		byte[] buf = new byte[1024];
		int len;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while ((len = bis.read(buf)) != -1) {
			baos.write(buf, 0, len);
			baos.flush();
		}
		byte[] byteArray = baos.toByteArray();
		// 将所有字节都异或成一个值,实现加密
		for (int i = 0; i < byteArray.length; i++) {
			byte b = byteArray[i];
			byteArray[i] = (byte) (b ^ 32);
		}
		bis.close();
		return byteArray;
	}
}

 

 

主程序

 

public class MyClassLoaderDemo {

	public static void main(String[] args) throws Exception {
		// Person p = new Person();
		// System.out.println(p);
		MyClassLoder classLoder = new MyClassLoder();
		Class clazz = classLoder
				.loadClass("/Users/yoofale/Documents/JAVASEworkspace/Practice/bin/com/practice922/Person.class");
		System.out.println(clazz.newInstance());
	}

	// 一个数异或一个数值两次,值是本身
	// int a = 10;
	// System.out.println(a = a ^ 89);
	// System.out.println(a = a ^ 89);
	public static void test() throws Exception {
		byte[] bytes = ClassUtils
				.XORClass("/Users/yoofale/Documents/JAVASEworkspace/Practice/bin/com/practice922/Person.class");
		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
		int len;
		byte[] buf = new byte[1024];
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(
				"/Users/yoofale/Documents/JAVASEworkspace/Practice/bin/com/practice922/Person.class"));
		while ((len = bais.read(buf)) != -1) {
			bos.write(buf, 0, len);
			bos.flush();
		}
		bos.close();
		System.out.println("加密成功");
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值