我已经阅读了很多关于这个主题的内容,似乎无法做到,但只是为了确定我还想再提出一个意见。
用例: 以编程方式与一个或多个https服务连接的Web应用程序,这些服务是动态的,证书会经常更新。
应用程序应该使用新证书更新TrustStore并在不重新启动应用程序的情况下使用它们。重要的是不应该实现新代码来执行https连接(因此,它应该无缝集成)。
我已经尝试(没有运气)覆盖默认的Java TrustManager,我们将不胜感激。
编辑:我已经尝试了评论/答案中提出的一些解决方案,但我仍然需要重新启动我的tomcat答案 0 :(得分:1)
虽然它在this other SO post的评论中发布,但我想将这种方法作为可能的答案,因为它也帮助我解决了这个问题。
本文介绍了如何创建一个新的SSLContext,其中包含围绕标准X509TrustManager的包装器(ReloadableX509TrustManager):https://jcalcote.wordpress.com/2010/06/22/managing-a-dynamic-java-trust-store/
每当对客户端/服务器进行身份验证(使用checkClientTrusted / checkServerTrusted)时,X509ReloadableTrustManager都会在其中调用X509TrustManager的相关方法。如果失败(抛出CertificateException),则它将在尝试进行另一次尝试之前重新加载TrustStore。实际上,每次“重新加载”都会用一个新实例替换X509TrustManager,因为我们无法触摸其中的证书。
我个人对本文的看法略有不同。在ReloadableX509TrustManager的checkClientTrusted / checkServerTrusted中:
为了减少文件I / O请求的数量,我跟踪了TrustStore上一次检查的时间戳,以将TrustStore上的轮询间隔限制为最少15秒。
我认为我的方法要好一些,因为它允许使用当前的TrustStore进行身份验证,该信任库也可以从中删除证书。即使删除了相关证书,原始方法仍将允许应用程序继续信任客户端/服务器。
编辑:回想起来,我认为重装过程应该是线程安全的,因为我找不到任何表明X509TrustManager中的checkClientTrusted()和checkServerTrusted()方法可能在设计时没有考虑线程安全的问题。实际上,默认X509TrustManagerImpl类的checkTrustedInit()方法具有一些同步块-这可能暗示这些函数必须是线程安全的。
答案 1 :(得分:-2)
似乎这个问题已在Programmatically Import CA trust cert into existing keystore file without using keytool得到解答。
我认为问题在于,信任库和密钥库实际上是相同的,但它们与密钥管理器一起用于私钥(客户端身份验证(通常不使用,没有真正的签名权限))和信任管理器用于服务器身份验证(总是完成完整的连接)。
以编程方式,您仍然在此方面使用密钥库作为信任库。希望我对此是正确的。