0

我的问题是:我有两个由 maven 构建的罐子。一个 jar 包含一个逻辑,该逻辑包装来自 jave.net.ssl 的一些类,以在 URL 中的方案为 https 时发出 https 请求:获得 HttpsUrlConnection 后,我将获得 SSLSocketFactory,如下所示:

private SSLSocketFactory prepareSSLSocketFactory(SecurityConfig secConfig) throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, KeyManagementException
{
    if (secConfig == null) throw new IllegalArgumentException("secConfig");
    if (sslSocketFactory!=null)
        return sslSocketFactory;

    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());      
    trustStore.load(secConfig.getSslTrustStore()/*ClassLoader.getSystemClassLoader().getResourceAsStream("jclienttruststore.jks")*/, secConfig.getSslTrustStorePassword().toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);
    SSLContext ctx = SSLContext.getInstance(secConfig.getSslAlgorithm());
    ctx.init(null, tmf.getTrustManagers(), null);
    sslSocketFactory = ctx.getSocketFactory();
    return sslSocketFactory;
}

请注意 secConfig.getSslTrustStore() 部分,因为它包含传递给此方法的 InputStream,在从 jar 的类中获取它之后,该类是包含上述代码的父类。获取InputStream如下:

protected InputStream obtainTrustStore() 
{                
    //InputStream stream = this.getClass().getClassLoader().getParent().getResourceAsStream("trustcert/jclienttruststore.jks");
    //InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");

    InputStream stream = this.getClass().getClassLoader().getResourceAsStream("trustcert/jclienttruststore.jks");
    return stream;
}       

资源定位成功,获得InputStream。但是在第一个片段上执行 trustStore.load() 时,我收到奇怪的异常,说 KeyStoreFormat 无效。KeyStoreFormat 是有效的 - 这是肯定的 - 因为当我从包含此 prepareSSLSocketFactory 的 jar 执行测试方法并加载相同的密钥库文件但位于当前 jar 的资源中时,根本没有例外,并且客户端通过 ssl 成功通信。

因此,我的观察如下:如果我从位于执行方法 prepareSSLSocketFactory 的 jar 中的密钥库资源中加载提供 InputStream 的 trustore,则它可以工作,但是如果另一个 jar 负责将 InputStream(带有密钥库)提供给包含 prepareSSLSocketFactory() 的依赖 jar - 它抛出异常。不知道如何处理它。

请注意,我已经通过调用检查了提供资源的类和包含 prepareSSLSocketFacory 的类是否由同一个 ClassLoader 加载:

this.getClass().getClassLoader().equals(HttpConnector.class.getClassLoader()) - 没关系。

从提供密钥库 InputStream 的类到底层的 https 请求生成类。

但是我不知道是否有可能,HttpConnector.class.getClassLoader() 返回的 ClassLoader 不是加载最后在运行时使用的 HttpConnector 的那个。

4

1 回答 1

0

现在问题已经解决了......而且更重要的是 - 答案不是真实的。问题与加载相同密钥库资源的不同类加载器无关,实际上其中一个资源(资源我的意思是由 keytool 生成的密钥库文件)在运行时被简单地损坏(因此异常“密钥库格式无效”是可以的)。这很难弄清楚,因为密钥库只生成一次,然后文件被复制到资源文件夹中。所以我假设它不会被损坏 - 它不是 - 因为我重建项目 - 在我的 Maven 构建中,我有一个资源插件,它为所有资源启用了过滤 - 这使得每次我构建项目时密钥库文件都损坏:)

于 2012-11-18T00:53:16.843 回答