我一直在我的程序中使用自定义 keystore ,方法是指定 javax.net.ssl.keyStore、javax.net.ssl.keyStorePassword、javax。 net.ssl.trustStore, javax.net.ssl.trustStorePassword。我的信任库包含自签名证书。现在我想发出一些 https 请求(比如 https://google.com )并使用包含不同 CA 信息的默认 jre 系统 trusstore。要发出 http 请求,我使用 OkHttp 库。它的客户端可以选择指定 SslSocketFactory,但要获得它,我需要为默认的 jre 信任库初始化 SSLContext。我该怎么做?
更新: 我使用的代码是
KeyStore keyStore = KeyStore.getInstance("JKS");
// load default jvm keystore
keyStore.load(new FileInputStream(
System.getProperties()
.getProperty("java.home") + File.separator
+ "lib" + File.separator + "security" + File.separator
+ "cacerts"), "changeit".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), new SecureRandom());
最佳答案
javax.net.ssl.*
系统属性会影响默认的 SSLContext
,它被 SSLSocketFactory.getDefault()
和SSLContext.getDefault()
返回的那个,如果您还没有使用自定义上下文使用 SSLContext.setDefault(...)
,那就是。
如果您想保留对某些连接(不是您使用这些自签名证书的连接)使用默认信任库的能力,则不应使用这些属性。相反,您应该让其他连接使用为那些自签名证书构建的 SSLContext
。 (你不能真的 get the default trust store with certainty otherwise ,至少不能不使用 JRE 中的私有(private) API。)
由于您正在使用的库允许您指定一个 SSLSocketFactory
,因此当您想要使用它时,可以从您的自定义 SSLContext
构建一个。 (如果需要,您也可以从默认的 SSLContext
为其他情况构建一个,尽管这通常是暗示的,如果该库在连接之间重置其设置。)
关于java - 获取 Java 中默认系统信任库的 SSLContext(JSEE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30519267/