• 总结加密、机密jar中的class


    1、加密和解密部署到jboss中间件中的的单个class文件,原理:使用“java源程序加密解决方案(基于Classloader解密) (2014-07-13 11:31)”blog即可实现;

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    //加密class文件
    public class EncryptionClass {
        public static void main(String[] args) throws Exception{
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/Program Files/jboss-4.0.5.GA/server/default/deploy/icmp.war/WEB-INF/classes/com/zzst/application/meeting/mcu/operate/rmx2000/RMX2000Sender2.class"));
            byte[] data = new byte[bis.available()];
            bis.read(data);
            bis.close();
            for(int i = 0; i < data.length; i++){
                data[i] =(byte)( data[i] + 1);
            }
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:/Program Files/jboss-4.0.5.GA/server/default/deploy/icmp.war/WEB-INF/classes/com/zzst/application/meeting/mcu/operate/rmx2000/RMX2000Sender2.class"));
            bos.write(data);
            bos.close();
        }
    }
    
    

    package com.zzst.application.mcuUtil.test;

    import java.io.BufferedInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;

    
    

    public class MyClassLoader extends NetworkClassLoader{

    String classpath;

    Map<String, Class> loadedClassPool = new HashMap<String, Class>();

    
    

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

    
    

    public MyClassLoader(String classpath, String otherBaseURL) {
    this.classpath = classpath;
    setBaseUrl(otherBaseURL);
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    Class claz = null;
    if (loadedClassPool.containsKey(name)) {
    claz = this.loadedClassPool.get(name);
    } else {

    
    

    try {
    if (claz == null) {
    claz = super.loadClass(name, false);
    if (claz != null) {
    System.out.println("系统加载成功:" + name);
    }
    }
    } catch (ClassNotFoundException e) {
    System.out.println("系统无法加载:" + name);
    }

    try {
    if (claz == null) {
    //解密RMX2000Sender2.class文件,然后再加载成Class
    if(name.equals("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2")){
    try{
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(classNameToPath(name)));
    byte[] data = new byte[bis.available()];
    bis.read(data);
    bis.close();
    for(int i = 0; i < data.length; i++){
    data[i] =(byte)( data[i] - 1);
    }
    //Class claz = defineClass(“Hello”, data, 0, data.length);
    System.out.println("============my class loader===============" + "com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2");
    claz = defineClass(name, data, 0, data.length);
    }catch(Exception e){
    e.printStackTrace();
    }
    }

    if (claz != null) {
    System.out.println("自定义解密 加载成功:" + name);
    }
    }
    } catch (Exception e) {
    System.out.println("自定义解密 无法加载:" + name);
    }

    try {
    if (claz == null) {
    claz = findClass(name);
    if (claz != null) {
    System.out.println("lib 系统加载成功:" + name);
    }
    }
    } catch (ClassNotFoundException e) {
    System.out.println("lib 系统无法加载:" + name);
    }

    try {
    if (claz == null) {
    claz = loadByCjClassLoader(name);
    if (claz != null) {
    System.out.println("自定义加载成功:" + name);
    }
    }
    } catch (Exception e) {
    System.out.println("自定义无法加载:" + name);
    }

    
    

    if (claz != null) {
    this.loadedClassPool.put(name, claz);
    }

    
    

    }
    if (resolve) {
    resolveClass(claz);
    }
    return claz;
    }

    
    

    /**
    *
    * 解密加载
    *
    *
    * @param name
    * @return
    */
    @SuppressWarnings("unchecked")
    private Class loadByCjClassLoader(String name) {
    Class claz = null;
    try {
    byte[] rawData = loadClassData(name);
    if (rawData != null) {
    /* 临时不解密
    byte[] classData = decrypt(getReverseCypher(this.cjcipher.getKeycode()), rawData);
    classData = CipherUtil.filter(classData, this.cjcipher);
    */


    byte[] classData = rawData;
    claz = defineClass(name, classData, 0, classData.length);
    }
    } catch (Exception e) {
    e.printStackTrace();
    claz = null;
    }
    return claz;
    }

    private byte[] loadClassData(String className) {

    
    

    String path = classNameToPath(className);

    
    

    try{

    
    

    InputStream ins = new FileInputStream(path);

    
    

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    
    

    int bufferSize = 4096;

    
    

    byte[] buffer = new byte[bufferSize];

    
    

    int bytesNumRead = 0;

    
    

    while ((bytesNumRead = ins.read(buffer)) != -1) {

    
    

    baos.write(buffer, 0, bytesNumRead);

    
    

    }

    
    

    return baos.toByteArray();

    
    

    } catch (IOException e) {

    
    

    e.printStackTrace();

    
    

    }

    
    

    return null;

    
    

    }

    
    

    private String classNameToPath(String className){
    return classpath + File.separatorChar + className.replace('.', File.separatorChar) + ".class";

    
    

    }

    }

     

    2、加密jar包中class文件:可采用先加密硬盘上的class文件,然后手动替换jar包中相同的class文件即可实现;

        加载第三方jar包中的class,可以通过继承URLClassLoader来实现;在应用程序中,如果想先解密jar包中的class文件,然后再加载的话,同样也可使用URLClassLoader类中的方法:

    
    

    package com.zzst.action.meeting.meeting;

    
    

    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.net.URLStreamHandlerFactory;
    import java.security.AccessController;
    import java.security.CodeSigner;
    import java.security.CodeSource;
    import java.security.PermissionCollection;
    import java.security.PrivilegedExceptionAction;
    import java.util.Enumeration;
    import java.util.jar.Manifest;

    
    

    import sun.misc.Resource;
    import sun.misc.URLClassPath;

    
    

    public class NetworkClassLoader extends URLClassLoader {

    
    

    String baseUrl;

    private URLClassPath myucp;

    
    

    public String getBaseUrl() {
    return baseUrl;
    }

    
    

    public void setBaseUrl(String baseUrl) {
    this.baseUrl = baseUrl;
    }

    
    

    public NetworkClassLoader(){
    this(new URL[]{});
    }

    
    

    /**
    * URL 以'/'结尾的为目录
    * 否则为jar包
    * 未指定其父类加载器为系统类加载器
    * @param urls
    */
    public NetworkClassLoader(URL[] urls) {
    super(urls);
    myucp = new URLClassPath(urls);
    }

    
    

    /**
    * 同上,指定classLoader
    * @param urls
    * @param parent
    */
    public NetworkClassLoader(URL[] urls, ClassLoader parent) {
    super(urls,parent);
    }

    
    

    /**
    * 同上,URL工厂处理器
    * @param urls
    * @param parent
    * @param factory
    */
    public NetworkClassLoader(URL[] urls, ClassLoader parent,
    URLStreamHandlerFactory factory) {
    super(urls,parent,factory);
    }

    
    

    /**
    * [添加baseUrl]
    * @param url
    */
    public void addURL(String url){
    URL uurl=null;
    try {
    uurl = new URL(baseUrl+url);
    } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    addURL(uurl);
    }

    
    

    /**
    * 添加url[添加baseUrl]
    */
    protected void addURL(URL url) {
    super.addURL(url);

    myucp.addURL(url);
    }

    
    

    /**
    * 返回urls
    */
    public URL[] getURLs() {
    return super.getURLs();
    }

    
    

    /**
    * 查找类对象
    * 从以上的URLS中查找加载当前类对象[会打开所有的jars去查找指定的类]
    * (可以通过调用findClass来得到以上URL加载包中的类)
    */
    public Class<?> findClass(String name) throws ClassNotFoundException {
    //return super.findClass(name);
    return myFindClass(name);
    }

    
    

    /**
    *此方法是从URLClassLoader类中拷贝出来的,用于读取第三方jar包中的class文件。
    */
    protected Class<?> myFindClass(final String name)
    throws ClassNotFoundException
    {
    try {
    return (Class)
    AccessController.doPrivileged(new PrivilegedExceptionAction() {
    public Object run() throws ClassNotFoundException {
    String path = name.replace('.', '/').concat(".class");
    Resource res = myucp.getResource(path, false);
    if (res != null) {
    try {
    return defineClass(name, res);
    } catch (IOException e) {
    throw new ClassNotFoundException(name, e);
    }
    } else {
    throw new ClassNotFoundException(name);
    }
    }
    }, AccessController.getContext());
    } catch (java.security.PrivilegedActionException pae) {
    throw (ClassNotFoundException) pae.getException();
    }
    }

    private Class defineClass(String name, Resource res) throws IOException {
    int i = name.lastIndexOf('.');
    URL url = res.getCodeSourceURL();
    if (i != -1) {
    String pkgname = name.substring(0, i);
    // Check if package already loaded.
    Package pkg = getPackage(pkgname);
    Manifest man = res.getManifest();
    if (pkg != null) {
    // Package found, so check package sealing.
    if (pkg.isSealed()) {
    // Verify that code source URL is the same.
    if (!pkg.isSealed(url)) {
    throw new SecurityException(
    "sealing violation: package " + pkgname + " is sealed");
    }

    
    

    } else {
    // Make sure we are not attempting to seal the package

    }
    } else {
    if (man != null) {
    definePackage(pkgname, man, url);
    } else {
    definePackage(pkgname, null, null, null, null, null, null, null);
    }
    }
    }
    // Now read the class bytes and define the class
    java.nio.ByteBuffer bb = res.getByteBuffer();
    if (bb != null) {
    // Use (direct) ByteBuffer:
    CodeSigner[] signers = res.getCodeSigners();
    CodeSource cs = new CodeSource(url, signers);
    return defineClass(name, bb, cs);
    } else {
    byte[] b = res.getBytes();
    System.out.println(name);

    //解密zzmcufv.jar中的RMX2000Sender2.class文件,然后在加载成class
    if(name.equals("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2")){ 
    for(int j = 0; j < b.length; j++){
    b[j] =(byte)( b[j] - 1);
    }
    }
    // must read certificates AFTER reading bytes.
    CodeSigner[] signers = res.getCodeSigners();
    CodeSource cs = new CodeSource(url, signers);
    return defineClass(name, b, 0, b.length, cs);
    }
    }

    
    


    /**
    * 查找资源[自定义相对URL查找路径]
    * 从以上的URLS中查找当前名称的资源
    * 这个必须重写,因为是public 哈哈
    */
    public URL findResource(String name) {
    URL url = null;
    try {
    url = new URL(baseUrl+name);
    } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    return url;
    }

    
    

    /**
    * 查找资源列表[URL查找路径]
    */
    public Enumeration<URL> findResources(String name) throws IOException {
    return super.findResources(name);
    }

    
    

    /**
    * 在当前的ClassLoader中,定义一个新的Package,Package的属性由Manifest指定.这个包的源文件
    */
    protected Package definePackage(String name, Manifest man, URL url)
    throws IllegalArgumentException {
    return super.definePackage(name, man, url);
    }

    
    

    /**
    * 加载路径权限
    */
    protected PermissionCollection getPermissions(CodeSource codesource) {
    return super.getPermissions(codesource);
    }
    }

     

      在业务代码中可以这么调用:

    NetworkClassLoader loader = new NetworkClassLoader();
    loader.setBaseUrl("file:///D:\Program Files\jboss-4.0.5.GA\server\default\deploy\icmp.war\WEB-INF\lib\");
    loader.addURL("comm.jar");
    loader.addURL("dom4j-1.6.1.jar");
    loader.addURL("log4j.jar");
    loader.addURL("commons-io-1.3.2.jar");
    loader.addURL("commons-logging-1.0.4.jar");
    loader.addURL("zzmcufv.jar");
    try {                 
            Class clazz= loader.findClass("com.zzst.application.meeting.mcu.operate.rmx2000.RMX2000Sender2");
            System.out.println(clazz.getName());
            Method taskMethod = clazz.getMethod("sendPost", String.class, String.class);//然后我们就可以用反射
            Object o = taskMethod.invoke(null,"http://10.1.6.30", "abcdefg");   
         System.out.println("info: " + (String)o); //String类型对象由同一个父类加载器生成,所以,大家都能使用!
    }
    catch (Exception e) { e.printStackTrace(); }
  • 相关阅读:
    ExtJs错误总结
    Java中的基本类型和引用类型(未完)
    【转】JavaScript中的全局变量与局部变量
    地理信息技术在现场项目的应用浅析
    vector的二分查找算法
    Linux命令
    封装 libmemcached
    Linux + boost + libmemcached + jsoncpp + mysql 配置
    SQL字符串处理函数大全(转)
    vector 排序方法sort的使用
  • 原文地址:https://www.cnblogs.com/wangle1001986/p/3841015.html
Copyright © 2020-2023  润新知