在运行时从资源设置默认 Java SSLContext
我的问题的基本组成部分是(上下文遵循代码片段)
- 以下代码是否是通过 -Djavax.net.ssl.keystore 设置默认 Java 密钥库的有效替代方案?
- 除了更改默认密钥和信任管理器之外,此代码可能会对受影响的 JVM 中的 SSL 行为产生什么影响
是否有更好的替代方法可以在运行时从资源?
KeyStore ks = KeyStore.getInstance("JKS"); ks.load(testService.class.getClassLoader().getResourceAsStream("resources/.keystore"), "changeit".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, "changeit".toCharArray()); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLContext.setDefault(ctx);
围绕这个问题的背景如下。我目前正在为具有相互证书身份验证的 Web 服务开发 CXF 客户端。由于各种原因,将客户端证书和密钥添加到默认密钥库并不是一个理想的选择。理想情况下,我正在寻找一种方法,将密钥库作为资源文件包含在 JAR 中,并根据需要在运行时将其设置为默认值。我还想避免在每个对象的基础上配置每个客户端和/或连接,并且还支持 JaxWsDynamicClientFactory 等操作(主要是为了“完整性”)。
我在互联网和SO上搜索相关材料并找到了这些(一个 ,<一href="https://stackoverflow.com/questions/859111/how-do-i-accept-a-self-signed-certificate-with-a-java-httpsurlconnection">两个)相关问题,但是所提供的解决方案都不是我正在寻找的(尽管我确实使用它们作为开发上面代码的跳板)。
现在,我意识到其他解决方案也可以发挥作用,但我正在/正在专门寻找一种能够满足所有这些要求的解决方案。
The basic components of my question are (context follows code snippet)
- Is the following code a valid alternative to setting the default Java keystore via the -Djavax.net.ssl.keystore?
- What impact, other than changing the default key and trust managers, might this code have on the behavior of SSL within the affected JVM
Is there a better alternative to setting the default trust/key stores, at run-time, from a resource?
KeyStore ks = KeyStore.getInstance("JKS"); ks.load(testService.class.getClassLoader().getResourceAsStream("resources/.keystore"), "changeit".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, "changeit".toCharArray()); SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLContext.setDefault(ctx);
The context surrounding this question is as follows. I am currently developing a CXF client for a web service with mutual certificate authentication. For various reasons, adding the client certificate and key to the default keystore is not a desirable option. Ideally, I was looking for a way include a keystore as a resource file in the JAR, and set it as the default at run-time, as the need arose. I also wanted to avoid configuring each client and/or connection on a per-object basis, and also support the operation of things such as JaxWsDynamicClientFactory (mostly for the sake of "completeness").
I scoured the internet and SO for relevant material and found these (one, two) related questions, but none of the solutions offered were exactly what I was looking for (although I did use them as a springboard to develop the code above).
Now, I realize that other solutions could be made to work, but I was/am specifically looking for a solution that would meet all of these requirements.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码将使用相同的密钥库(从类加载器加载)作为默认密钥库和默认信任库。这实际上相当于将
-Djavax.net.ssl.keystore*
和-Djavax.net.ssl.truststore*
设置为相同的值。如果这就是您想要做的,那很好。 (不过,在加载密钥库后,您可能需要关闭
InputStream
。)这将影响整个 JVM 以及使用
SSLContext.getDefault()
的所有内容,特别是依赖于默认SSLSocketFactory
的所有内容(URLConnection
等)。由于这将是您的默认信任存储区,因此来自主要 CA 的默认受信任 CA 证书不会位于您的信任存储区中,除非您还显式地将它们导入到从类加载器加载的副本中。
据推测,您不会有大量新的 CA(或自签名)证书可供信任。将密钥库和信任库分开可能会更方便,因为您的信任库可能对大多数客户端来说都是通用的,并且通常只是一开始的一次性配置步骤。
Your code will use the same keystore (loaded from the classloader) as the default key store and the default trust store. That's effectively equivalent to setting both
-Djavax.net.ssl.keystore*
and-Djavax.net.ssl.truststore*
with the same value.This is fine if that's what you want to do. (You may want to close the
InputStream
once you've loaded the keystore, though.)This will affect the entire JVM, and everything that uses
SSLContext.getDefault()
, in particular everything that relies on the defaultSSLSocketFactory
(URLConnection
and so on).Since this will be your default trust store, the default trusted CA certificates from the major CAs won't be in your trust store unless you've also explicitly imported them into the copy you load from the classloader.
Presumably, you won't have a large number of new CA (or self-signed) certificates to trust. It might be more convenient to keep the keystore and truststore separated, since your truststore might be common to most of your clients, and it would usually just be a one-off configuration step at the beginning.