- 浏览: 226907 次
- 性别:
- 来自: 北京
最新评论
-
lzj0470:
这种方式,带来的问题很大。如:返回一个对象,然后再调用一些办法 ...
自定义classloader加密java程序 -
bushkarl:
JavaScript 胸罩尺寸计算器 -
bushkarl:
...
Ubuntu php 环境配置 -
dearsunkey:
hao !
Ubuntu php 环境配置 -
qskm:
这个怎么用呢?楼主没说清楚啊,
1、 加密的话该怎么加密?直接 ...
自定义classloader加密java程序
大概想法是这样的:
1. 生成密钥用于在des算法中加密。
2. classloader类中动态的解密class,并且通过反射机制执行main方法。
3. 对classloader类进行高质量的混淆。
首先需要生成des算法中的key:
有了key之后就可以对class进行加密了:
然后还是关键的classloader类:
最后解密,并且通过反射机制执行:
其中源文件是这样的:
就可以了。
1. 生成密钥用于在des算法中加密。
2. classloader类中动态的解密class,并且通过反射机制执行main方法。
3. 对classloader类进行高质量的混淆。
首先需要生成des算法中的key:
import java.io.File; import java.io.FileOutputStream; import java.security.SecureRandom; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; class Key { private String keyName; public Key() { } public Key(String keyName) { this.keyName = keyName; } public void createKey(String keyName) throws Exception { SecureRandom sr = new SecureRandom(); KeyGenerator kg = KeyGenerator.getInstance("DES"); kg.init(sr); SecretKey key = kg.generateKey(); System.out.println(key.toString()); byte rawKeyData[] = key.getEncoded(); FileOutputStream fo = new FileOutputStream(new File(keyName)); fo.write(rawKeyData); fo.close(); } public static void main(String args[]) { try { new Key("").createKey("d:/key.txt"); } catch (Exception e) { e.printStackTrace(); } } }
有了key之后就可以对class进行加密了:
package com.hitachi.crypt; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; public class Crypt { public static void main(String[] args) throws Exception { SecureRandom sr = new SecureRandom(); FileInputStream fi = new FileInputStream(new File("d:/key.txt")); byte rawKeyData[] = new byte[fi.available()]; fi.read(rawKeyData); fi.close(); DESKeySpec dks = new DESKeySpec(rawKeyData); SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key, sr); FileInputStream fi2 = new FileInputStream(new File("d:/HelloWorld.class")); byte data[] = new byte[fi2.available()]; fi2.read(data); fi2.close(); byte encryptedData[] = cipher.doFinal(data); FileOutputStream fo = new FileOutputStream(new File("d:/HelloWorld.class")); fo.write(encryptedData); fo.close(); } }
然后还是关键的classloader类:
package com.hitachi.classloader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Hashtable; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; public class MyClassLoader extends ClassLoader { private static String myClasspath = new String(""); private static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>(); private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>(); public MyClassLoader() { } /** */ /** * create a classloader and specify a classpath. * * @param myClasspath * the specified classpath name. */ public MyClassLoader(String myClasspath) { if (!myClasspath.endsWith("\\")) { myClasspath = myClasspath + "\\"; } MyClassLoader.myClasspath = myClasspath; } /** */ /** * set the classpath * * @param myClasspath * the specified classpath name */ public void SetmyClasspath(String myClasspath) { if (!myClasspath.endsWith("\\")) { myClasspath = myClasspath + "\\"; } MyClassLoader.myClasspath = myClasspath; } /** */ /** * Loads the class with the specified binary name. This method searches for * classes in the same manner as the loadClass(String, boolean) method. * Invoking this method is equivalent to invoking {loadClass(name,false)}. * * @param className * The binary name of the class. * * @return The resulting <tt>Class</tt> object. * * @throws ClassNotFoundException * If the class was not found. */ @SuppressWarnings("unchecked") public Class loadClass(String className) throws ClassNotFoundException { return loadClass(className, false); } /** */ /** * Loads the class with the specified binary name. The default * implementation of this method searches for classes in the following * order: * * Invoke {findLoadedClass(String)} to check if the class has already been * loaded. * * Invoke {findSystemClass(String)} to load the system class. * * Invoke the {findClass(String)} method to find the class. * * If the class was found using the above steps, and the resolve flag is * true, this method will then invoke the {resolveClass(Class)} method on * the resulting Class object. * * @param name * The binary name of the class. * * @param resolve * If true then resolve the class. * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class could not be found. */ @SuppressWarnings("unchecked") protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { try { Class foundClass = findLoadedClass(name); // check if the class has already been loaded. if (foundClass != null) { System.out.println("Complete to load the class: " + name); return foundClass; } // if the class is systemClass, load the system class by system if (name.startsWith("java.")) { foundClass = findSystemClass(name); loadClassHashTable.put(name, foundClass); System.out.println("System is loading the class: " + name); return foundClass; } // invoke the findClass() method to load the class try { foundClass = findClass(name); } catch (Exception fnfe) { } if (resolve && (foundClass != null)) { resolveClass(foundClass); } return foundClass; } catch (Exception e) { throw new ClassNotFoundException(e.toString()); } } /** */ /** * Finds the class with the specified binary name.The default implementation * throws a ClassNotFoundException. * * @param className * The binary name of the class. * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class could not be found. */ @SuppressWarnings("unchecked") public Class findClass(String className) { byte[] classData = null; try { classData = loadClassData(className); } catch (IOException e) { e.printStackTrace(); } if (classData == null) { return null; } System.out.println("MyClassLoader is loading : " + className + ""); Class c = defineClass(className, classData, 0, classData.length); MyClassLoader.loadClassHashTable.put(className, c); System.out.println("Complete to load the class :" + className); return c; } /** */ /** * Loads the classData with the specified binary name. This method searches * for classes in the specified classpath as * searchFile(myClasspath,className) method. * * @param name * The binary name of the class * * @return The resulting the classData of the class object by byte[] * * @throws IOException * if have some failed or interrupted I/O operations. */ private byte[] loadClassData(String className) throws IOException { String filePath = searchFile(myClasspath, className + ".class"); if (!(filePath == null || filePath == "")) { System.out.println("It have found the file : " + className + ". Begin to read the data and load the class。"); FileInputStream inFile = new FileInputStream(filePath); byte[] classData = new byte[inFile.available()]; inFile.read(classData); inFile.close(); loadClassTime.put(className, new File(filePath).lastModified()); return classData; } else { filePath = searchFile(myClasspath, className + ".java"); if (!(filePath == null || filePath == "")) { System.out.println("It have found the file : " + filePath + ". Begin to translate"); Runtime.getRuntime().exec("javac " + filePath); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Translate it over : " + filePath); return loadClassData(className); } else { System.out .println("Haven't found the file, and fail to read the classData!"); return null; } } } /** */ /** * Loads the class with the specified binary name.The default implementation * throws a ClassNotFoundException. * * @param classData * The data of the class. * @param className * The binary name of the class. * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class could not be found. */ public Class loadClass(byte[] classData, String className) throws ClassNotFoundException { System.out.println("MyClassLoader is loading : " + className + ""); Class c = defineClass(className, classData, 0, classData.length); loadClassHashTable.put(className, c); System.out.println("Complete to load the class :" + className); return c; } /** */ /** * Loads the class with the specified binary name.The default implementation * throws a ClassNotFoundException. * * @param className * The binary name of the class. * @param jarName * The binary name of the jar that search the class from it. * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class could not be found. */ protected Class loadClass(String className, String jarName) throws ClassNotFoundException { String jarPath = searchFile(myClasspath, jarName + ".jar"); JarInputStream in = null; if (!(jarPath == null || jarPath == "")) { try { in = new JarInputStream(new FileInputStream(jarPath)); JarEntry entry; while ((entry = in.getNextJarEntry()) != null) { String outFileName = entry.getName().substring( entry.getName().lastIndexOf("/") + 1, entry.getName().length()); if (outFileName.equals(className + ".class")) { if (entry.getSize() == -1) { System.err.println("error : can't read the file!"); return null; } byte[] classData = new byte[(int) entry.getSize()]; System.out .println("It have found the file : " + className + ". Begin to read the data and load the class。"); in.read(classData); return loadClass(classData, className); } } System.out.println("Haven't found the file " + className + " in " + jarName + ".jar."); } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } else { System.out.println("Haven't found the jarFile: " + jarName + ".jar."); return null; } return null; } /** */ /** * Reloads the class with the specified binary name. Needn't have to restart * JVM then reload the class. * * @param className * The binary name of the class need to reload . * * @return The resulting Class object. * * @throws ClassNotFoundException * If the class was not found. */ public Class reload(String fileName) { String filePath = searchFile(myClasspath, fileName + ".class"); Long a = new File(filePath).lastModified(); if (!a.equals(loadClassTime.get(fileName))) { loadClassHashTable.remove(fileName); loadClassTime.remove(fileName); try { MyClassLoader mc2 = new MyClassLoader(myClasspath); mc2.loadClass(fileName); } catch (ClassNotFoundException e) { e.printStackTrace(); } } else { System.out .println("The class is the newest version , needn't reloading."); } return null; } /** */ /** * search the file with the specified binary name. Needn't have to restart * JVM then reload the class. * * @param classpath * the specified path where we search. * @param fileName * The binary name of the file that want to search. * * @return The resulting file path. */ public String searchFile(String classpath, String fileName) { String cut = fileName.substring(fileName.lastIndexOf('.'), fileName .length()); String path = fileName.substring(0, fileName.lastIndexOf('.')).replace( '.', '/') + cut; File f = new File(classpath + path); if (f.isFile()) { return f.getPath(); } else { String objects[] = new File(classpath).list(); for (int i = 0; i < objects.length; i++) { if (new File(classpath + File.separator + objects[i]) .isDirectory()) { String s = searchFile(classpath + objects[i] + File.separator, fileName); if (s == null || s == "") { continue; } else { return s; } } } } return null; }; }
最后解密,并且通过反射机制执行:
package com.hitachi.crypt; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.Method; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import com.hitachi.classloader.MyClassLoader; public class Decrypt { public static void main(String[] args) throws Exception { SecureRandom sr = new SecureRandom(); FileInputStream fi = new FileInputStream(new File("d:/key.txt")); byte rawKeyData[] = new byte[fi.available()]; fi.read(rawKeyData); fi.close(); DESKeySpec dks = new DESKeySpec(rawKeyData); SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key, sr); FileInputStream fi2 = new FileInputStream(new File( "D:/HelloWorld.class")); byte encryptedData[] = new byte[fi2.available()]; fi2.read(encryptedData); fi2.close(); byte decryptedData[] = cipher.doFinal(encryptedData); MyClassLoader mcl = new MyClassLoader("D:/"); Class cl = mcl.loadClass(decryptedData, "HelloWorld"); Method mainMethod = cl.getMethod("sayHello"); mainMethod.invoke(null, null); } }
其中源文件是这样的:
public class HelloWorld { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Hello world"); } public static void sayHello() { System.out.println("Hello"); } }
就可以了。
评论
4 楼
lzj0470
2011-12-24
这种方式,带来的问题很大。如:返回一个对象,然后再调用一些办法
3 楼
qskm
2010-07-22
这个怎么用呢?楼主没说清楚啊,
1、 加密的话该怎么加密?直接执行Crypt类,一个一个加密class文件还是怎么整?
2、 加载class的classloader类是放在哪里?需要配置还是如何调用的?
3、 基于ssh的系统能用不?
4、 ???
1、 加密的话该怎么加密?直接执行Crypt类,一个一个加密class文件还是怎么整?
2、 加载class的classloader类是放在哪里?需要配置还是如何调用的?
3、 基于ssh的系统能用不?
4、 ???
2 楼
thxg
2009-11-08
博主好,请教一个classloader相关的问题,我用classloader加载了一个jar文件,用完之后希望可以跟据用户意愿删掉这个jar文件,但据说VM不退出,就不会释放,就无法删除,有什么好办法解决这个问题吗?参考问答模块的链接:
http://www.iteye.com/problems/28854
http://www.iteye.com/problems/28854
1 楼
雁行
2009-06-12
好复杂啊
参考一下
参考一下
发表评论
-
JavaScript 胸罩尺寸计算器
2008-11-30 10:45 2474只在周末放松一下 ;) Ed Spencer 已经用Java ... -
JDB 的简单使用
2008-11-24 10:08 1320当新手开始学习Java 时 ... -
dr.scheme中不能输入字符问题的解决
2008-11-02 20:23 1724LANG=C drscheme -
mit-scheme出现HEAP_IN_LOW_MEMORY错误的解决办法
2008-11-01 22:29 1410sudo sysctl -w vm.mmap_min_addr ... -
linux下的GTKLookAndFeel.initSystemColorDefaults异常
2008-10-26 16:25 1300不能使用SystemLookAndFeel,不知跟发行版有没有 ... -
我的emacs配置文件~
2008-10-26 00:29 3460贴在这,免得以后丢了还得写~ (setq default ... -
Linux操作系统中如何使用ISO文件
2008-08-17 22:02 20951.什么是ISO文件? ISO文件:就是以iso为扩展名的文 ... -
深入了解laptop_mode
2008-08-16 11:28 5685对UBUNTU6.06LTS中切入Laptop_mode模式的 ... -
VIM 快捷键(转)
2008-08-10 14:56 2319VIM快捷键: ctags 文件名 ... -
hardy的vim语法高亮
2008-08-10 14:54 1612hardy自带的vim不是完全版的,所以在设置syntax o ... -
ubuntu handy编译google gadgets
2008-08-10 11:40 1274simple step by step instruction ... -
在linux下转换psp的mp4
2008-08-09 23:00 1420开始使用mencoder,比较麻烦,参数总调整不好,http: ... -
Alpine Messaging System, the alternative to Pine.
2008-08-02 16:12 1091I just tried Alpine the email p ... -
lftp中文问题
2008-07-19 09:33 1446<!-- @page { si ... -
The greatest equations ever
2008-07-17 15:48 1178Maxwell's equations of electrom ... -
只许你大步的向前走
2008-05-07 01:14 1286借用许飞的一句歌词,这几天把《恰许同学年少》这张听了n遍,真该 ... -
java socket-message-作业慢慢写~今天就到这
2008-05-04 21:10 1618package org.tiantian.message.se ... -
Html解析生成纯文本-使用SAX以及htmlcleaner
2008-04-22 01:00 2065package testlucene; import jav ... -
从HTML抽取纯文本
2008-04-20 23:28 1797spider中需要提取纯文本: 1.javax.swing.t ... -
JSP使用多线程
2008-04-20 23:23 1662spider之中需要使用多线程去抓取网页,本来还有点疑惑,没想 ...
相关推荐
自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨自定义Classloader的使用。 一、Classloader的工作原理 Java的类加载机制遵循双亲...
在程序运行时,通过自定义的`ClassLoader`,在加载类之前先解密这些加密的字节码,然后再交给JVM执行。这样可以增加逆向工程的难度,防止代码被恶意分析或篡改。加密解密的过程通常涉及到对字节码的操作,例如使用...
### Java ClassLoader理解详解 ...自定义ClassLoader不仅能够扩展JVM的功能,还能够在实际项目中解决特定问题,如动态加载远程资源、加密类文件等。希望这篇教程能为你提供足够的背景知识,以便在实践中应用这些技术。
加密Java源代码 ,使用自定义classloader加载器和加密解密技术实现
本文主要探讨了两种常见的Java加密策略:自定义ClassLoader加密和混淆技术。 首先,我们关注自定义ClassLoader的加密方法。Java的类加载机制允许开发者创建自己的ClassLoader子类,通过这个机制可以实现对类的加密...
【如何有效防止Java程序源码被人偷窥】 Java程序的源代码保护是一个重要的议题,因为一旦源码被窃取,可能会导致知识产权的流失,甚至可能导致安全风险。在Java中,由于其字节码的可读性,源码很容易通过反编译器被...
2. **Class文件加密**:对敏感的Class文件进行加密,然后在运行时通过自定义ClassLoader解密并加载。虽然这增加了反编译的难度,但自定义ClassLoader本身可能会成为攻击目标,一旦解密密钥或算法被破解,加密的Class...
自定义ClassLoader是Java平台的一大特色,开发人员可以根据需要创建自己的类加载器,例如实现模块化、热部署或者加密解密类等高级功能。自定义ClassLoader通常需要重写findClass()或loadClass()方法,以控制类的加载...
下面将通过一个简单的示例来展示如何使用自定义ClassLoader来实现Java源代码的加密与解密。 1. **创建自定义ClassLoader**: - 自定义ClassLoader需要重写`findClass`方法来处理加密后的类文件。 - 在`findClass`...
- 在某些特殊情况下,我们可能需要自定义ClassLoader来实现特定的加载逻辑,例如从网络、数据库或加密文件中加载类。 - 自定义ClassLoader通常需要重写`loadClass()`方法,该方法在找不到类时调用`findClass()`...
例如,本加密工具安装在c:\hideasoft\java_protect,执行加密后的CLASS文件的命令行如下: java -agentlib:c:\hideasoft\java_protect\hidea <您的CLASS类及参数> 应用场合 独立的应用程序(Application,...
- 应用程序沙箱:在沙箱环境中运行应用程序,通过自定义ClassLoader来控制加载的类的安全性。 - 模块化/插件化:对于需要模块化或插件化的应用程序,可以通过自定义ClassLoader实现模块的热加载或动态卸载。 深入...
不同于C或C++程序,Java程序由多个独立的类文件组成,每个文件对应一个Java类。ClassLoader的工作机制允许Java程序在运行时动态加载类,从而提供了更大的灵活性和扩展性。 Java的ClassLoader分为几个层次,包括...
通过对Java ClassLoader的深入了解,我们可以更好地理解Java类的加载机制以及如何通过自定义ClassLoader来满足特定的应用需求。淘宝网的成功实践为我们提供了宝贵的参考案例,展示了ClassLoaders在实际项目中的重要...
- 尽管加密和自定义ClassLoader可以增加安全性,但是Java的JVM本身可能存在安全漏洞,允许黑客绕过这些保护措施。因此,还需要结合使用Java的安全管理器和策略文件,限制代码的执行权限,防止恶意代码对系统资源的...
总之,ClassLoader是Java运行时环境中的关键组件,理解其工作原理和如何自定义ClassLoader对于提高开发者的技术深度和解决问题的能力具有重要意义。通过阅读源码和实践,我们可以更深入地掌握这一领域,从而在实际...
1. 自定义需求:在某些场景下,如动态加载插件、加密类文件等,开发者可能需要自定义ClassLoader。自定义ClassLoader需要继承java.lang.ClassLoader并重写findClass()方法。 2. 实现步骤:创建类加载器实例,读取类...
《深入Java虚拟机_ClassLoader》是一本专注于Java虚拟机(JVM)中ClassLoader部分的专著,旨在帮助读者深入理解Java程序如何加载、链接和初始化类。ClassLoader是Java平台核心特性的一部分,它负责查找和加载类到JVM...
在这个主题中,我们将深入探讨三个关键知识点:Java中的类加载器(ClassLoader)在加密解密中的应用、常见的加密算法以及Java提供的加密技术。 首先,让我们来看看Java的类加载器如何在加密解密中发挥作用。类加载...