httpclient 4.x
方法 1
通过调试选项配置 TrustStrore
-Djavax.net.ssl.trustStore=/Users/amodpandey/.keystore
即使不传递密码(信任库的密码),Java 也能够读取信任库
但即使在这之后你也可能面临
javax.net.ssl.SSLPeerUnverifiedException: 主机名 'localhost' 与对等方提供的证书主题不匹配 ...
CloseableHttpClient httpClient =
HttpClientBuilder.create()
.setSSLHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
})
.build();
它有效..
方法2
全部放在代码中
CloseableHttpClient httpClient =
HttpClientBuilder.create()
.setSslcontext(SSLContexts.custom().loadTrustMaterial(new File(Thread.currentThread().getContextClassLoader().getResource("keystore").getFile())).build())
.setSSLHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
})
.build();
方法 3
使用连接管理器时
使用时忽略setSslcontext和setSSLHostnameVerifier
.setConnectionManager(connectionManager)
所以应该配置连接管理器
Files.copy(ClassLoader.getSystemResourceAsStream("keystore"), Paths.get(URI.create("file:/tmp/keystore")),
StandardCopyOption.REPLACE_EXISTING);
Registry<ConnectionSocketFactory> socketFactoryRegistry =
RegistryBuilder
.<ConnectionSocketFactory>create()
.register(
"https",
new SSLConnectionSocketFactory(SSLContextBuilder.create()
.loadTrustMaterial(new File("/tmp/keystore")).build(),
new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})).register("http", PlainConnectionSocketFactory.INSTANCE).build();
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(socketFactoryRegistry);
CloseableHttpClient httpClient =
HttpClientBuilder.create()
.setConnectionManager(connectionManager)
.build();
注意
-
-Djavax.net.debug=all 调试选项非常有助于查看正在使用的证书
-
SSLContext 使用 File,如果我们计划将证书与代码一起打包到 Jar 中,那么我们需要创建一个文件以将其传递给 File 对象(它不适用于 jar 中的文件)
Files.copy(ClassLoader.getSystemResourceAsStream("keystore"),Paths.get(URI.create("file:/tmp/utskeystore")),StandardCopyOption.REPLACE_EXISTING)