码迷,mamicode.com
首页 > 其他好文 > 详细

自定义类加载器+加密+解密 实验

时间:2015-05-16 20:07:50      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

自定义类加载器+加密+解密  的这个程序需要的实验步骤如下,所用的类如下:

ClassLoaderTest  类:用来做“解密实验”的类,将Test类的加密后的.class文件加载内存,并解密后,用ClassLoader.defineClass()得到Class对象,利用反射使用Test类

MyClassLoader  类:定义自己的类加载器,重写其中的findClass方法,在该方法中定义查找.class文件的默认目录,并调用EncodeDecodeClass类的解密方法,解密Test.class,然后调用父类的defineClass方法,得到Class对象。

EncodeDecodeClass   类:定义了加密和解密方法

Test  类:定义了一个普通类,这个类的正确的.class会被加密和解密

UseTest 类:用来做“加密实验”测试的类,里面使用了加密后的Test.class

1、“加密实验”

    1.0  设置好classpath的值

    1.1  先用javac正常编译Test.java(用带存储路径的方式编译带包名的类,以用来正确的到包的文件夹形式,并将类存放到正确位置),得到正确的.class文件

    1.2  先调用EncodeDecodeClass.encode()方法,对已经存在的正确的Test.class文件加密,得到Test_1.class

    1.3  用javac 正常编译UseTest.java,得到编译后的UseTest.class (这里也可以看到这个UsetTest.class文件中只包含了UseTest类的信息,并不包含它所用到的

      类Test.class的信息,即一个.class中只包含其对应的类的本类信息,不包含这个类的定义中用到的其他类的定义信息,编译器只是在编译出本类的.class文件的时候

      通过用反射加载类进内存,检查被使用类身上是否有某个方法的这个方式来检查本类的源程序.java,是否是正确的,即本类是否被正确定义了,只是检查,为的是

      保证运行的时候,可以正确的运行,运行的时候JVM会利用类加载器来动态加载类中使用的其他类的.class文件信息,来完成程序的运行)

    1.4  将Test_1.class 改名为Test.class,将原来的那个正确的Test.class删除掉

    1.5  用 java 运行UsetTest.class类,报告出异常

                  技术分享

    实验完毕,报告出异常说明了加密实验成功!!

2、“解密实验”

   1.0   设置好classpath的值

   1.1   先用javac编译ClassLoaderTest.java,得到ClassLoaderTest.class

   1.2   再用java 运行ClassLoaderTest.class

   1.3   成功调用,打印出结果:

          技术分享

   实验完毕,打印以上信息,说明解密实验成功!!

【实际项目中,将开发好的框架(或者类)的.class文件统一进行加密,然后交给客户使用,客户如果直接拿来使用,则会出错,.class里面的数据是错误的数据,无法解析。

如果客户付费后,则可以用一个验证码的方式激活自定义的类加载器中的解密方法(if 语句判断一下用户是否获得了验证码,没有则不调用解密方法),正确加载框架中的类

,并解析他们,完成正确的使用。】

 

ClassLoaderTest.java

package com.heima;

import java.io.File;
import java.lang.reflect.Method;
/*自定义类加载器,对.class文件进行加载,同时编写对.class文件进行加密和解密的程序*/
/*
 * 
 * 

        "Exception in thread "main" java.lang.ClassFormatError: Incompatible magic value
        889275713 in class file com/heima/Test" ---->这个异常指的是程序中使用的已经存在的类文件(即.class文件)是有问题的。
        比如,将.class文件加密后,再在主类.class中使用这个.class文件,在类加载器ClassLoader将类从.class文件中加载到内存的对类的处理过程中,
        就会抛出这个异常。
        incompatible :不兼容的 ,矛盾的
        magic :不可思议的 ,有魔力的
 * 
 */

public class ClassLoaderTest {
    
    public static void main(String[] args) {
        
        System.out.println("ok");
        try {
            Class clazz = new MyClassLoader().loadClass("com.heima.Test");
            Method method = clazz.getMethod("print");
            method.invoke(clazz.newInstance());
            System.out.println("解密调用成功!");
        } catch (Exception e) {
            
            e.printStackTrace();
        }

    }

}

 

MyClassLoader 

package com.heima;

import java.io.File;

public class MyClassLoader extends ClassLoader {

    private String path ="F:\\myclass\\";
    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
        
        String tempName = name.replaceAll("\\.","\\\\"); //将类的完全限定名称中的包名之间的.转换为
        File file = new File(path,tempName+".class"); //拼接出正确的类名,得到正确的抽象路径名
        

        byte[] buf = null;
        System.out.println("***************** "+name+"  "+file.exists()); //测试信息
        System.out.println(file.toString());
        if(file.exists())
        {
            try {
                buf = EncodeDecodeClass.decode(file); //解密指定的文件,得到字节码数组
            } catch (Exception e) {
                System.out.println("类文件解密出错!");
            }
        }
        Class retVal = defineClass(name, buf, 0, buf.length); //得到Class对象
        
        return retVal; //返回Class类对象
    }
}

 

EncodeDecodeClass   

package com.heima;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class EncodeDecodeClass {
    
    public static void encode(File file)throws Exception
    {
        FileInputStream fis = new FileInputStream(file);
        
        String name = file.getName();
        file.getPath();
        String[] strs = name.split("\\.");
        
        System.out.println(file.toString()+" :: "+name+" :: "+strs.length);
        name = strs[0]+"_1."+strs[1];
        file.renameTo(new File(file.getParent(),file.getName()+"_1"));
        
        File desFile = new File(file.getParent(),name);
        
        FileOutputStream fos = new FileOutputStream(desFile);
        byte[] buf = new byte[1024];
        int len = 0;
        while( (len = fis.read(buf))!=-1)
        {
            for(int i=0; i<len ;i++)
            {
                buf[i] = (byte)(buf[i]^0xff);//取反加密
            }
            fos.write(buf,0,len);
        }
        
        fis.close();
        fos.close();
        
    }
    public static byte[] decode(File file) throws Exception
    {
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream dest = new ByteArrayOutputStream();
        
        byte[] buf = new byte[1024];
        int len = 0;
        while((len = fis.read(buf))!=-1)
        {
            for(int i=0; i<len ;i++)
            {
                buf[i] = (byte)(buf[i]^0xff); //取反解密
            }
            dest.write(buf, 0, len);
        }
        fis.close();
        System.out.println("ok");
        return dest.toByteArray();
    }
    public static void main(String[] args)
    {
        File file = new File("f:\\myclass\\com\\heima\\Test.class");
        if(file.exists())
        {
            try {
                EncodeDecodeClass.encode(file);
                System.out.println("加密成功!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

Test.java

package com.heima;

public class Test {

    public void print()
    {
        System.out.println("自定义类加载器要加载类的代码,我在被要先被加密,刚刚才解密");
    }
    
    public static void main(String[] args) {
        
        
        System.out.println(0xff);

    }

}

 

UseTest.java

package com.heima;

public class UseTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Test t = new Test();
        t.print();
    }

}

 

自定义类加载器+加密+解密 实验

标签:

原文地址:http://www.cnblogs.com/wllbelief-win/p/4508370.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!