javax.net.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 registry = RegistryBuilder.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); }
我花了一个小时试图解决同样的问题。 这就是我提出的:
final SSLConnectionSocketFactory sslsf; try { sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(), NoopHostnameVerifier.INSTANCE); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } final Registry registry = RegistryBuilder. create() .register("http", new PlainConnectionSocketFactory()) .register("https", sslsf) .build(); final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); cm.setMaxTotal(100); httpClient = HttpClients.custom() .setSSLSocketFactory(sslsf) .setConnectionManager(cm) .build();
希望它可以工作,不使用任何弃用的代码(httpclient 4.4.1)。
替换它
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf) .setConnectionManager(cm).build();
同
CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .setConnectionManager(cm) .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) .build();
如果证书没有签名(甚至没有自签名),那么你可以这样做
import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class TrustAllStrategy implements TrustStrategy { @Override public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }
然后
builder.loadTrustMaterial(new TrustAllStrategy());
编辑:这个
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, //for you this is builder.build() SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );
感谢所有的解决方案。 我一直在网上试用所有解决方案1.5天,最后它现在运行了。 这是工作代码
SSLContextBuilder builder = new SSLContextBuilder(); builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE); Registry registry = RegistryBuilder. create() .register("http", new PlainConnectionSocketFactory()) .register("https", sslConnectionSocketFactory) .build(); PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); cm.setMaxTotal(100); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslConnectionSocketFactory) .setConnectionManager(cm) .build(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(postEntity); httpPost.expectContinue(); CloseableHttpResponse response = httpclient.execute(httpPost);
这就是我提出的:
SSLContextBuilder sslcontext = new SSLContextBuilder(); sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy()); httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) .build();
在尝试了本页面上建议的大部分解决方案以及其他相关的stackoverflow讨论之后,我发现AJC的上述响应与apache httpclient 4.5版一起使用。
原因:如果在构造函数中未指定HostVerifier,则创建SSLConnectionSocketFactory时,不会设置它并使用DefaultHostVerifier。 因此,AJC解决方案的第3行产生了不同之处。
(至少这是apache httpclient 4.5.3中的行为)
- 如何在Java中更改HTTP响应中的字符集编码
- 修复java.net.SocketTimeoutException:读取超时
- HTTPSURLconnection和Apache(系统)DefaultHttpClient之间的证书链不同
- 如何将使用HttpClient下载的文件保存到特定文件夹中
- 如何使用Google Drive REST AP和HTTPClient创建文件夹?
- 如何使用RestTemplate为每个请求设置RequestConfiguration?
- 在HTTPClient 4.1中使用文件和字符串进行多部分POST
- java filechannel cpu用法随着时间的推移而增长
- 什么是apache中的SchemeRegistry以及何时应该使用它?