我有一个java密钥库,可以用它连接到受保护的https第三方服务。在初始化web客户端时,我会在代码中明确使用此密钥库:
// Solution #1
String password = "changeit";
KeyStore keyStore = KeyStore.getInstance(new File("src/main/resources/keystore.jks"), password.toCharArray());
SSLContext sslContext = new SSLContextBuilder()
.loadKeyMaterial(keyStore, password.toCharArray())
.build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, (hostname, session) -> true);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
使用这种方法,一切都正常。
但我也知道有可能指定系统变量 javax.net.ssl.keyStore
以及 javax.net.ssl.keyStorePassword
. 因此,我希望上述代码的替代解决方案也能奏效:
// Solution #2
System.setProperty( "javax.net.ssl.keyStore", "src/main/resources/keystore.jks");
System.setProperty( "javax.net.ssl.keyStorePassword", "changeit");
HttpClient httpClient = HttpClients.createDefault();
在这里,我创建了一个默认的web客户机,而没有显式地用密钥库构造sslcontext。我希望默认的web客户机会自动从中获取密钥库 javax.net.ssl.keyStore
. 但这似乎没有采取,这个解决方案不适合我。
所以我想知道使用系统属性的目的是什么 javax.net.ssl.keyStore
? 它如何有用?这里的最佳做法是什么?
3条答案
按热度按时间jtoj6r0c1#
您可以执行与第一个解决方案类似的操作,但必须将密码作为
String
,密码应在properties
在运行时加载的文件,或在启动jvm时将其指定为环境变量。我想说的重点是密码不应该在代码中。
对于第二个解决方案,您可能需要检查
trustStore
环境变量。https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslserver.html
8wtpewkr2#
与@bruno在如何访问jvm默认密钥库中的答案相对应?没有默认值
KeyStore
在 java 。这意味着如果你用这也需要在代码中解析它们,比如
然后在你的
HttpClient
(如在Solution #1
). 换句话说,只需指定keyStore
如果您不手动解析它们,也不将它们用于HttpClient
. 这就是我在发布问题时试图理解的。这是与系统属性的一个重要区别
TrustStore
喜欢指定这些属性不需要任何额外的代码。因为有一个默认值
TustStore
将由自动创建JVM
从属性。那么httpClient
将只使用默认值TrustStore
没有开发商的任何努力。mnemlml83#
设置信任库
javax.net.ssl.trustStore
为公众证书提供外部服务。javax.net.ssl.keyStore
用于在https上运行时存储您的私有证书。另外,我建议从一个单独的属性文件加载属性(特别是密码),如lé哦,施耐德。
更新您关于
javax.net.ssl
属性,这些属性是定义信任库和密钥库属性的替代方法。它是有用的b/c不是所有的库都允许sslcontext作为可能需要的输入(例如不支持ssl的遗留库)。此外,还可以直接从命令行定义这些属性,从而提高可用性。