此问题在此处已有答案:
How can I use different certificates on specific connections?(5个答案)
去年关闭。
截至6天前,社区正在审查是否重新讨论这个问题。
我正在用Java编写一个应用程序,它通过HTTPS连接到两个Web服务器。一个通过默认的信任链获得受信任的证书,另一个使用自签名证书。当然,连接到第一台服务器是开箱即用的,而连接到使用自签名证书的服务器是不起作用的,直到我使用来自该服务器的证书创建了一个trustStore。但是,到默认受信任服务器的连接不再起作用,因为显然,一旦我创建了自己的信任存储,默认的信任存储就会被忽略。
我发现的一个解决方案是将默认trustStore中的证书添加到我自己的证书中。但是,我不喜欢这个解决方案,因为它需要我继续管理那个trustStore。(我不能假设这些证书在可预见的未来保持不变,对吗?)
除此之外,我发现两个5岁的线程有类似的问题:
Registering multiple keystores in JVM的
How can I have multiple SSL certificates for a Java server的
它们都深入到Java SSL基础设施中。我希望现在有一个更方便的解决方案,我可以在代码的安全审查中轻松解释。
5条答案
按热度按时间r1zk6ea11#
您可以使用与我在previous answer中提到的模式类似的模式(针对不同的问题)。
实际上,获取默认信任管理器,创建使用您自己的信任存储的第二个信任管理器。将它们都 Package 在一个自定义信任管理器实现中,该实现将调用委托给这两个对象(当其中一个失败时,回退到另一个对象)。
字符串
您不必将该上下文设置为默认上下文。如何使用它取决于您正在使用的客户端库(以及它从何处获取其套接字工厂)。
也就是说,原则上,无论如何都必须根据需要更新信任库。Java 7 JSSE参考指南对此有一个“重要说明”,现在在同一指南的版本8中降级为“说明”:
JDK在java-home/lib/security/cacerts文件中附带了有限数量的受信任根证书。如keytool参考页中所述,如果您将此文件用作信任库,则您有责任维护(即添加和删除)此文件中包含的证书。
根据您联系的服务器的证书配置,您可能需要添加其他根证书。从相应的供应商处获取所需的特定根证书。
4dc9hkyq2#
也许我晚了6年才回答这个问题,但它可能对其他开发人员也有帮助。我还遇到了加载默认信任库和我自己的自定义信任库的相同挑战。在多个项目中使用相同的定制解决方案之后,我认为创建一个库并将其公开以回馈社区会很方便。请看这里:Github - SSLContext-Kickstart
使用方法:
字符串
我不太确定我是否应该在这里发布这篇文章,因为它也可以被视为推广“我的库”的一种方式,但我认为它对那些有同样挑战的开发人员可能会有帮助。
您可以使用以下代码段添加依赖项:
型
h5qlskok3#
可以通过调用
TrustManagerFactory.init((KeyStore)null)
检索默认信任存储区并获取其X509Certificate
。将其与您自己的证书结合使用。您可以使用KeyStore.load
从.jks
或.p12
文件加载自签名证书,也可以通过CertificateFactory
加载.crt
(或.cer
)文件。下面是一些演示代码来说明这一点。如果使用浏览器从www.example.com下载证书,则可以运行代码stackoverflow.com。如果注解掉添加加载的证书和默认证书,代码将得到
SSLHandshakeException
,但如果保留其中任何一个,它将返回状态代码200。字符串
odopli944#
下面是Bruno's answer的更简洁版本
字符串
xdyibdwo5#
正如我所理解的,您还可以使用Apache HttpComponents库中的
SSLContextBuilder
类将您的自定义密钥库添加到SSLContext
:字符串