java忽略证书验证(兼容http,https)进行get/post请求--使用(org.apache.httpcomponents httpclient客户端)

这两天的任务就是跟测试接触,在测试过程发送数据请求上游信息时,报了:

javax.net.ssl.SSLException: hostname in certificate didn't match

截图:
java忽略证书验证(兼容http,https)进行get/post请求--使用(org.apache.httpcomponents httpclient客户端)
文章图片

含义就是说现在程序运行的域名,与请求的证书不一致,不匹配导致的。那么解决方案必定是把证书忽略了,也就是不验证证书的情况下请求上游信息了。
在解决这个问题的过程中。领导给过我一个demo,可惜这个demo是org.apache.httpcomponents 4.5版本的,而项目中用到的是org.apache.httpcomponents 4.3.6的,两者有一些区别 经过仔细看底层代码,最后发现,其实是否忽视证书的验证,关键还是要看这个截图的第一行:
java忽略证书验证(兼容http,https)进行get/post请求--使用(org.apache.httpcomponents httpclient客户端)
文章图片

也就是底层的实现,需要用到Abstractactverifier.verify这个类的这个方法,源码如下:
@Override public final boolean verify(final String host, final SSLSession session) { try { final Certificate[] certs = session.getPeerCertificates(); final X509Certificate x509 = (X509Certificate) certs[0]; verify(host, x509); return true; } catch(final SSLException ex) { if (log.isDebugEnabled()) { log.debug(ex.getMessage(), ex); } return false; } }

关键点不让他去验证即可。
解决方法如下:
(看方法注释即可,注释有忽略验证的,就可以把这方法拷贝使用)
package util; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.net.ssl.*; import java.io.*; import java.net.HttpURLConnection; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Iterator; import java.util.Map; /** * Http 客户端请求 * * @author leaflyhuang */ @Component("cn.webank.pmbank.cftac.common.util.HttpClientUtil") public class HttpClientUtil {private final static Logger LOG = LoggerFactory.getLogger(HttpClientUtil.class); //提交信息-可以POST数据 public static Object submit(String url, boolean isHttps, HttpMethod httpMethod, EntityType entityType, byte[] bytes) throws SocketException { if (isHttps) { System.setProperty("jsse.enableSNIExtension", "false"); }HttpURLConnection conn = null; try { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; }public void checkClientTrusted(X509Certificate[] certs, String authType) { }public void checkServerTrusted(X509Certificate[] certs, String authType) { } }}; // Install the all-trusting trust managerSSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); URL conUrl = new URL(url); conn = (HttpURLConnection) conUrl.openConnection(); conn.setReadTimeout(35000); conn.setConnectTimeout(35000); if (httpMethod == HttpMethod.POST || bytes != null) { conn.setDoOutput(true); } conn.setDoInput(true); conn.connect(); if (bytes != null) { DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream()); outputStream.write(bytes); outputStream.flush(); outputStream.close(); }// if (conn.getResponseCode() >= 200 && conn.getResponseCode() < // 300) { InputStream inputStream = conn.getInputStream(); if (inputStream != null) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ((length = inputStream.read(buffer)) != -1) { stream.write(buffer, 0, length); } inputStream.close(); if (entityType == EntityType.STRING) { return stream.toString(); } return stream.toByteArray(); } // } else { // throw new Exception(url + " server return " // + conn.getResponseCode() + " status"); // } } catch (SocketException | SocketTimeoutException socketException) {throw new SocketException("SocketException: " + socketException.getMessage()); } catch (Exception e) {} finally { if (conn != null) { conn.disconnect(); } } return null; }private CloseableHttpClient closeableHttpClient = null; @Value("${proxy.ip:}") private String proxyIp; @Value("${proxy.port:0}") private int proxyPort; //get 请求 public String getEntity(String url, boolean isHttps, int timeout) throws IllegalArgumentException, IOException { if (isHttps) { System.setProperty("jsse.enableSNIExtension", "false"); }if (closeableHttpClient == null) { //closeableHttpClient = createHttpClientWithProxy(); closeableHttpClient = createNoVerifyClient(); } HttpGet httpGet = new HttpGet(url); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build(); httpGet.setConfig(requestConfig); try (CloseableHttpResponse response = closeableHttpClient.execute(httpGet)) { int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { return null; } HttpEntity entity = response.getEntity(); byte[] byteArray = EntityUtils.toByteArray(entity); String ret = new String(byteArray); return ret; } catch (Exception e) {return null; }} //post请求 public Object postEntity(String url, Map paramsMap, boolean isHttps, int timeout) throws IllegalArgumentException, IOException { if (isHttps) { System.setProperty("jsse.enableSNIExtension", "false"); } MultipartEntityBuilder builder = MultipartEntityBuilder.create(); Iterator iterator = paramsMap.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); Object value = https://www.it610.com/article/paramsMap.get(key); if (value instanceof File) { FileBody fileBody = new FileBody((File) value); builder.addPart(key, fileBody); } else if (value instanceof byte[]) { byte[] byteVlue = (byte[]) value; ByteArrayBody byteArrayBody = new ByteArrayBody(byteVlue, key); builder.addPart(key, byteArrayBody); } else { throw new IllegalArgumentException("未知数据类型!目前仅支持file类型与byte类型"); } } closeableHttpClient = createNoVerifyClient(); HttpPost httpPost = new HttpPost(url); HttpEntity build = builder.build(); httpPost.setEntity(build); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build(); httpPost.setConfig(requestConfig); try (CloseableHttpResponse response = closeableHttpClient.execute(httpPost)) { int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { return null; } HttpEntity entity = response.getEntity(); byte[] byteArray = EntityUtils.toByteArray(entity); String ret = new String(byteArray); return (Object) ret; }} //没有忽略证书创建 CloseableHttpClient private CloseableHttpClient createHttpClientWithProxy() { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); //代理 if (StringUtils.isNotBlank(proxyIp)) { HttpHost proxy = new HttpHost(proxyIp, proxyPort, "http"); httpClientBuilder.setProxy(proxy); } httpClientBuilder.setMaxConnTotal(200); httpClientBuilder.setMaxConnPerRoute(100); closeableHttpClient = httpClientBuilder.build(); return closeableHttpClient; } /** * 忽视所有证书验证-使用org.apache.httpcomponents 4.5版本 */ public static CloseableHttpClient acceptsUntrustedCertsHttpClient(String proxyHost, int proxyPort) throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); // setup a Trust Strategy that allows all certificates. SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); httpClientBuilder.setSslcontext(sslContext); // don't check Hostnames, either. // use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken //final X509HostnameVerifier hostnameVerifier = getX509HostnameVerifier(); HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; //org.apache.httpcomponents 4.3.6版本没有的 // here's the special part: // -- need to create an SSL Socket Factory, to use our weakened "trust strategy"; // -- and create a Registry, to register it. SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, null); Registry socketFactoryRegistry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory).build(); // now, we create connection-manager using our Registry. allows multi-threaded use PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry); connMgr.setMaxTotal(200); connMgr.setDefaultMaxPerRoute(100); httpClientBuilder.setConnectionManager(connMgr); HttpHost httpHost = new HttpHost(proxyHost, proxyPort); httpClientBuilder.setProxy(httpHost); // finally, build the HttpClient; CloseableHttpClient client = httpClientBuilder.build(); return client; }/** * 忽视所有证书验证使用org.apache.httpcomponents 4.3.6版本 */ public CloseableHttpClient createNoVerifyClient() { try { TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; }public void checkClientTrusted(X509Certificate[] certs, String authType) { }public void checkServerTrusted(X509Certificate[] certs, String authType) { } }}; // Install the all-trusting trust managerSSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sc); HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslsf); //代理 if (StringUtils.isNotBlank(proxyIp)) { HttpHost proxy = new HttpHost(proxyIp, proxyPort); httpClientBuilder.setProxy(proxy); } httpClientBuilder.setMaxConnTotal(200); httpClientBuilder.setMaxConnPerRoute(100); closeableHttpClient = httpClientBuilder.build(); return closeableHttpClient; } catch (KeyManagementException e) {} catch (NoSuchAlgorithmException e) {} return HttpClients.createDefault(); } }

【java忽略证书验证(兼容http,https)进行get/post请求--使用(org.apache.httpcomponents httpclient客户端)】下次遇到这问题,希望能以最快的速度解决,是本文章的目的!

    推荐阅读