首页 > 解决方案 > 使用自定义类加载器加载安全类

问题描述

我们正在创建一个基于 javassist 的自定义类加载器,在加载时修改一些类字节码。该项目的一部分也是一个包含安全提供程序的签名 jar。

Loader 的初始化简单如下:

private final Loader initLoader(ClassLoader master) {
    final ClassPool pool = ClassPool.getDefault();
    final Loader loader = new Loader(master, pool);
    try {
        loader.addTranslator(pool, new MyTranslator());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return loader;
}

该类MyTranslator进行修改,但不关心与安全相关的类。是master系统(父)类加载器。

当应用程序在加载相关安全类时进入该部分时,将引发此异常:

Caused by: java.security.NoSuchProviderException: JCE cannot authenticate the provider EXAMPLE-PROV
    at javax.crypto.JceSecurity.getInstance(JceSecurity.java:100) ~[?:1.8.0_121]
    at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
    at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]
    ... 22 more
Caused by: java.util.jar.JarException: Class is on the bootclasspath
    at javax.crypto.JarVerifier.verify(JarVerifier.java:286) ~[?:1.8.0_121]
    at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:159) ~[?:1.8.0_121]
    at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:185) ~[?:1.8.0_121]
    at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97) ~[?:1.8.0_121]
    at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
    at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]

我的问题是,是否有办法从自定义类加载器加载这些类而不违反 java 安全机制?

方法javassist.Loader#setDomain(ProtectionDomain)

如果不注册适当的保护域,则此加载程序加载的程序将无法与安全管理器或签名的 jar 文件一起使用。

如何创建或确定有效ProtectionDomain实例?

标签: javasecurityclassloaderjavassist

解决方案


推荐阅读