通过URLCassloader加载加密的JarFile

我一直在编写一个小系统来动态加载AES加密的jar文件。 我的代码:

public static void main(String args[]) throws Exception { String jar = "http://site.com/api/rsc/test.jar"; List urls = new ArrayList(); 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) 

我错过了什么吗? 谢谢你的时间。 =)

您正在为URLClassLoader添加加密jar的URL。 你如何期望URLClassLoader在加载时解密jar?

您最好的选择是实现自定义类加载器。 扩展SecureClassLoader并实现相关方法。 在ClassLoader javadocs中有一个基本的例子。