加密类加载器

3
我使用Java创建了一个“反转RSA”(使用私钥加密)框架,并希望将其扩展到在运行时加载类。我知道这对于防止我的代码被窃取并不是一种有效的保护措施,但我的目标是尽力防止人们更改我的代码。
过去几个小时,我一直在搜索一种方法来在运行时加载类(在此处找到了一些答案,但没有一个能帮助我),只给出一个包含解密的Jar文件的字节数组。我正在使用自定义的Classloader,它应该加载下面看到的.class文件:
public class MemoryClassLoader extends ClassLoader{
private byte[] current = null;

public MemoryClassLoader(){
    super(ClassLoader.getSystemClassLoader());
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
    Class res = null;
    try {
        res = defineClass(name, current,0,current.length,null);
    }catch(SecurityException e) {
        System.out.println("Could not load the Class with our custom method(" + e.getMessage() + ")  Falling back to the super method.");
        res = super.loadClass(name,true);
    }catch(Exception e){
        System.out.println("An error occured while loading the class: " + e.getMessage());
    }
    return res;
}

@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
    return findClass(name);
}

public final void setContents(final byte[] data){
    current = new byte[data.length];
    System.arraycopy(data, 0, current, 0, data.length);
}

我这样填充装载器:
```html

我这样填充装载器:

```
    public final void loadClasses(final File jarFile) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, InstantiationException{
    JarInputStream in = new JarInputStream(new ByteArrayInputStream(decrypt(jarFile)));//Block-like decryption 
    JarEntry je;
    MemoryClassLoader loader = new MemoryClassLoader();
    byte[] buffer = new byte[251658240];//30 MB
    while((je=in.getNextJarEntry())!=null){
        if(je.isDirectory() || !je.getName().endsWith(".class"))continue;
        in.read(buffer);
        buffer = trim(buffer);//Trim off all 0's at the end
        loader.setContents(buffer);
        Class c = loader.loadClass(je.getName().substring(0,je.getName().length()-6).replace("/", "."));//Try to load the class
    }
    in.close();
}

解密已成功,但类加载器在控制台中打印出“无法使用我们的自定义方法(被禁止的包名称:java.lang)加载类”,然后使用上级加载类的方法,令人惊讶地工作正常(因为原始文件仍然被加密)。虽然这样可行,但我的问题是,为什么会出现这个错误,我应该如何修复它?
提前感谢您的回答, Daniel
1个回答

3

我认为您当前的类加载器正在尝试加载Java SDK类,这就是为什么您会收到那个错误。请检查findClass()中的包名称,并使用系统类加载器来加载不在您的包中的类。


就这么简单,也许我工作时间太长了。我正在检查名称是否以java开头,然后使用Systems类加载器。谢谢! - Ch4t4r
不用谢,顺便说一下,白名单的方法可能更好。 - unknown
那肯定是最好的方式,但我猜结果会一样。 - Ch4t4r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接