我一直在编写一个小系统来动态加载AES加密的jar文件。 我的代码:
public static void main(String args[]) throws Exception {
String jar = "http://site.com/api/rsc/test.jar";
List<URL> urls = new ArrayList<URL>();
urls.add(getURL(jar));
URL jarurl = urls.get(0);
ObjectInputStream ois = new ObjectInputStream((new URL("http://site.com/api/rsc/key_1.txt").openStream()));
Object o = ois.readObject();
DESKeySpec ks = new DESKeySpec((byte[])o);
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey key = skf.generateSecret(ks);
Cipher c = Cipher.getInstance("DES/CFB8/NoPadding");
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec((byte[]) ois.readObject()));
CipherInputStream cis = new CipherInputStream((jarurl.openStream()), c);
JarInputStream jis = new JarInputStream(cis);
String main = jis.getManifest().getMainAttributes().getValue("Main-Class");
String classpaths[] = jis.getManifest().getMainAttributes().getValue("Class-Path").split(" ");
for (String classpath: classpaths) {
urls.add(getURL(classpath));
}
URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[0]));
Class<?> cls = loader.loadClass(main);
Thread.currentThread().setContextClassLoader(loader);
Method m = cls.getMethod("main", new Class[]{new String[0].getClass()});
m.invoke(null, new Object[]{args});
}
这只适用于普通的InputStream,我之前已经能够用Cipher代码解密文件和读取内容。当我尝试运行一个简单的hello world应用程序时,这就是它抛出的错误:
Exception in thread "main" java.lang.ClassNotFoundException: helloworld.Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at jarloader.JarLoader.main(JarLoader.java:63)
我错过了什么吗?谢谢你的时间。 =)
答案 0 :(得分:1)
您正在为加密的jar添加url到URLClassLoader。你怎么期望URLClassLoader在加载它时解密它?
您最好的选择是实现自定义类加载器。扩展SecureClassLoader并实现相关方法。 ClassLoader javadocs中有一个基本的例子。