【问题标题】:How can I load keystore using resource from another jar.如何使用来自另一个 jar 的资源加载密钥库。
【发布时间】:2012-11-16 10:33:31
【问题描述】:

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

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

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

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

从向底层 https 请求类提供密钥库 InputStream 的类。

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

【问题讨论】:

    标签: ssl https classloader keystore httpsurlconnection


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2015-02-19
      • 1970-01-01
      • 1970-01-01
      • 2011-02-27
      • 2012-07-25
      • 2019-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多