javajavax。网ssl。SSLPeerUnverifiedException:主机名与对等方提供的证书主题不匹配
我关注stackoverflow上的许多链接,并尝试了许多解决方案,但没有一个对我有效。我正在使用WSO2 API manager
版本1.9.1
。我面临以下错误:
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: Host name 'XXXXXXXXX' does not match the certificate subject provided by the peer (CN=localhost, O=WSO2, L=Mountain View, ST=CA, C=US)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at com.java.pushNotifications.WSO2DemoClient.main(WSO2DemoClient.java:49)
我开发了以下Java代码。请帮助我这里出了什么问题。我需要以不安全的方式连接,并允许在没有证书的情况下连接到SSL站点
public static void main(String[] args) throws ClientProtocolException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);//max connection
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(cm).build();
HttpGet httpGet = new HttpGet("https://XXXXXXXXXX:8243/token");
CloseableHttpResponse response = httpclient.execute(httpGet);
String json =" {\"data\":\"grant_type=password&username=test&password=test123\"}";
try {
HttpPost httpost = new HttpPost(url);
httpost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpost.setHeader("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
httpost.setEntity(new StringEntity(json));
HttpResponse httpResponse = httpclient.execute(httpost);
System.out.println(httpResponse.getStatusLine());
}
finally {
response.close();
}
String responseString1 = new BasicResponseHandler().handleResponse(response);
System.out.println("Response : "+responseString1);
}
# 1 楼答案
在尝试了本页上建议的大多数解决方案以及其他相关的stackoverflow讨论之后,我发现AJC的上述回应适用于ApacheHttpClient版本4.5
原因: 在创建SSLConnectionSocketFactory时,如果在构造函数中未指定HostVerifier,则不会设置它并使用DefaultHostVerifier。所以AJC解决方案的第3行起了作用
(至少这是apache httpclient 4.5.3中的行为)
# 2 楼答案
我花了一个小时试图解决同样的问题。这就是我的想法:
希望它能工作,并且不使用任何不推荐的代码(httpclient 4.4.1)
# 3 楼答案
这就是我想到的:
# 4 楼答案
换掉这个
与
如果证书没有签名(甚至没有自签名),那么您可以这样做
然后
编辑:这个
# 5 楼答案
感谢所有的解决方案。我已经在网上尝试了1.5天的所有解决方案,现在终于成功了。这是工作代码