記錄一下訪問https報doesn‘t contain CN or DNS sub錯誤
阿新 • • 發佈:2018-09-06
lse mail main follow rust log 版本說明 def end 版本說明
.setHostnameVerifier(hostnameVerifier)
.setSslcontext(sslcontext).build();
增加變量
public static X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {@Override
br/>@Override
return true;
}
httpclinet:4.3.1
jdk:1.6
tomcat:6
異常信息
Caused by: javax.net.ssl.SSLException: Certificate for <**> doesn‘t contain CN or DNS subjectAlt at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:178) at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:152) at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:133) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:291) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:262) at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:357) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:218) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) ... 18 more
背景
使用httpclient忽略證書發起https請求,代碼如下
package cn.org.pcac.ries.httpService.util; import java.io.IOException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpsSend { public static void main(String[] args) throws Exception { String url = ""; List<NameValuePair> formparams = new ArrayList<NameValuePair>(); HttpPost httpPost = new HttpPost(url); // 設置客戶超時 RequestConfig defaultRequestConfig = RequestConfig.custom() .setSocketTimeout(9000).setConnectTimeout(9000) .setConnectionRequestTimeout(9000) .setStaleConnectionCheckEnabled(true).build(); // 設置服務端 RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) .build(); formparams.add(new BasicNameValuePair("param", "")); httpPost.setConfig(requestConfig); CloseableHttpClient httpclient = null; httpclient = HttpClients.custom() .setDefaultRequestConfig(defaultRequestConfig).build(); SSLContext sslcontext = null; if (url.indexOf("https") == 0) { sslcontext = createIgnoreVerifySSL(); httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig) .setSslcontext(sslcontext).build(); } UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8"); httpPost.setEntity(uefEntity); HttpResponse response = httpclient.execute(httpPost); HttpEntity entity = response.getEntity(); if (entity != null) { // 獲得返回報文 String respons = EntityUtils.toString(entity, "UTF-8"); EntityUtils.consume(entity); System.out.println(respons); } } public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sc = SSLContext.getInstance("TLS"); X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } }; sc.init(null, new TrustManager[] { trustManager }, null); return sc; } }
錯誤原因
跟蹤源碼,異常信息如下所示:
訪問網站的證書為自簽證書,缺少CN=等信息,但是我已經忽略證書校驗了為什麽還會出現這個問題呢?
發現初始化CloseableHttpClient時,有如下代碼:
因此修改初始化CloseableHttpClient,將
httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig)
.setSslcontext(sslcontext).build();
改成
httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig)
.setSslcontext(sslcontext).build();
增加變量
public static X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {@Override
br/>@Override
return true;
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts)
throws SSLException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
};
記錄一下訪問https報doesn‘t contain CN or DNS sub錯誤