gpt4 book ai didi

java - 自定义类加载器的问题

转载 作者:行者123 更新时间:2023-12-01 05:57:58 25 4
gpt4 key购买 nike

我想实现一个自定义类加载器,以便对我的 jar 文件进行数字签名。由于性能问题,我不想加密我的所有类(class)。所以我想实现一个自定义类加载器,当它被调用时它将类委托(delegate)给它的父级,如果父级无法加载类,它会自行处理。这是我的代码:

package org.dpdouran.attach;
import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.spec.AlgorithmParameterSpec;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CustomClassLoader extends ClassLoader {
private static final int BUFFER_SIZE = 8192;
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
System.out.println("loading... "+className);
String clsFile = className.replace('.', '/') + ".class";
InputStream in = getResourceAsStream(clsFile);
if(in==null)
return null;
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int n = -1;
try {
while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, n);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//do decrypt
byte[] classBytes = out.toByteArray();
byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C,
0x07, 0x72, 0x6F, 0x5A };
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
Cipher dcipher=null;
try {
dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte keyBytes[] = "abcdEFGH".getBytes();
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "DES");
try {
dcipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] dbytes = null;
try {
dbytes = dcipher.doFinal(classBytes);
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return defineClass(className, dbytes, 0, dbytes.length);
}
public CustomClassLoader( ClassLoader parent){
super(sun.misc.Launcher.getLauncher().getClassLoader());
}
}

我还通过更改“java.system.class.loader”属性更改了默认系统类加载器。当我运行我的应用程序时,它可以很好地处理未加密的类,但是当它到达加密的类时,它会抛出 ClassFormatError 并且我的 findClasses 方法永远不会被调用!我如何确定我的自定义类加载器将在加密类上调用?谢谢

最佳答案

尝试以编程方式设置类加载器并查看它是否有效

Thread.currentThread().setContextClassLoader(myClassLoader);

当我实现类加载器时,我实现了 loadClass 方法而不是 findClass。尝试做类似的事情

try {
return super.loadClass(name);
catch (Exception e) {
... your code here
}

另一方面,文档说不要覆盖 loadClass,而是覆盖 findClass。

//编辑

另一个想法。

看来您将加密的类与未加密的 .class 文件一起保留。所以看起来父类加载器找到了正确的 .class 文件并且永远不会调用您的 findClass。但是class文件的格式是错误的,因为它是加密的。顺序是 my.loadClass->parent.loadClass->parent.loadClass ... ->my.findClass

所以你必须确保父类加载器找不到该类。只需重命名加密的类 - 给它们另一个扩展名或将它们保存在单独的文件夹中。

这应该可以解决问题

关于java - 自定义类加载器的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2279317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com