如何在Java SSL客户端应用程序中支持多个TrustStore

问题描述 投票:7回答:2

在我们的Java应用程序中,我们需要使用https协议与SSL上的服务器列表进行通信。要通信的服务器列表将在运行时更改。最初,我们没有任何服务器的证书。在运行时,我们将获取新服务器的证书,并将公钥证书添加到信任库中;并且与服务器的任何新https连接都应使用更新的信任库。

我们认为我们应该使用两个信任库,一个是cacerts(默认情况下是jre附带的一个),另一个包含我们在列表中动态添加/删除的服务器的证书。这将确保我们不会修改Java的默认TrustStore(cacerts)。

请建议如何实现。另外,是否有任何方法可以仅对Java中的特定线程使用特定的信任库,以便其他(现有的和新的)线程仍应使用默认的java trueststore(cacerts),并且一个特定的线程将对特定的信任库使用特定的信任库。服务器。

谢谢,迪帕克

java ssl certificate truststore
2个回答
5
投票

如果要动态导入证书,则可能需要使用自定义x509TrustManager。这是在配置SSLContext时完成的,它本身用于创建SSLContextSSLSocketFactory

SSLEngine是一个库,可用于包装现有的信任管理器并自定义某些设置。您不需要它,但可能会有所帮助。

这将遵循以下原则:

jSSLutils

PKIXSSLContextFactory sslContextFactory = new PKIXSSLContextFactory(); sslContextFactory.setTrustManagerWrapper(new X509TrustManagerWrapper() { @Override public X509TrustManager wrapTrustManager(final X509TrustManager origManager) { return new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return origManager.getAcceptedIssuers(); } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { try { // This will call the default trust manager // which will throw an exception if it doesn't know the certificate origManager.checkServerTrusted(chain, authType); } catch (CertificateException e) { // If it throws an exception, check what this exception is // the server certificate is in chain[0], you could // implement a callback to the user to accept/refuse } } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { origManager.checkClientTrusted(chain, authType); } }; } }); SSLContext sslContext = sslContextFactory.buildSSLContext(); (PKIX)SSLContextFactory来自jSSLutils,其余的可用于J2SE / J2EE。]

您可能想捕获一些X509TrustManagerWrapper(请参阅子类)。如果对用户进行回调,则SSL / TLS连接可能会由于SSL / TLS握手超时(如果回调花费太长时间而无法回复)而首次失败。

然后,您可以使用CertificateExceptions(来自Java 6)将此CertificateException作为默认值,但这不一定是一个好主意。如果可以,请将SSLContext传递到建立SSL / TLS连接的库。这样做的方式各不相同,但是例如,Apache HTTP Client 4.x具有多个选项来配置其SSL设置,其中一个选项是通过传递SSLContext.setSSLContext(...),另一个是通过传递SSLContext

您还可以通过检查KeyStore中的当前线程,为每个线程而不是要连接的每个对象(依赖于库):在同步和线程管理方面,这可能会使事情变得更加复杂/信任管理器的“意识”。


2
投票

这个问题太老了,我怀疑我的观点会帮助任何人,但是这里有用...

© www.soinside.com 2019 - 2024. All rights reserved.