我们在发请求时,会遇到需要ssl证书验证的报错,针对该错误以及所使用的不同的创建连接的方式,进行ssl证书忽略
忽略SSL证书的流程
简介:需要告诉client使用一个不同的TrustManager。TrustManager是一个检查给定的证书是否有效的类。SSL使用的模式是X.509,对于该模式Java有一个特定的TrustManager,称为X509TrustManager。首先我们需要创建这样的TrustManager。将TrustManager设置到我们的HttpClient。TrustManager只是被SSL的Socket所使用。Socket通过SocketFactory创建。对于SSL Socket,有一个SSLSocketFactory。当创建新的SSLSocketFactory时,你需要传入SSLContext到它的构造方法中。在SSLContext中,我们将包含我们新创建的TrustManager。
- 创建的TrustManager
- 创建SSLContext:TLS是SSL的继承者,但是它们使用相同的SSLContext。
- 创建SSLSocketFactory
- 将SSLSocketFactory注册到我们的HttpClient上。这是在SchemeRegistry中完成的。
- 创建ClientConnectionManager,创建SchemeRegistry。
- 生成HttpClient
http忽略ssl认证
忽略https认证,就是自己构建一个x509认证,默认通过,再传到ssl配置工厂中
1. httpClient忽略ssl证书连接
client发起请求时,使用已经构建过认证client发起请求
package com.neo.address.parse;/*** @author caoying* @since 2024/4/14*/import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;public class WebTool2 {public static void main(String[] args) {//String url = "https://www.stats.gov.cn/sj/tjbz/tjyqhdmhcxhfdm/2023/";try {String html = fetchPageContent(url);List<String> provinces = extractDataByTag(html, "tr", "provincetr");List<String> cities = extractDataByTag(html, "tr", "citytr");List<String> counties = extractDataByTag(html, "tr", "countytr");List<String> towns = extractDataByTag(html, "tr", "towntr");// 输出提取的数据System.out.println("Provinces: " + provinces);System.out.println("Cities: " + cities);System.out.println("Counties: " + counties);System.out.println("Towns: " + towns);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {throw new RuntimeException(e);}}private static String fetchPageContent(String url) throws IOException {// CloseableHttpClient httpClient = HttpClients.createDefault();HttpGet request = new HttpGet(url);try {//忽略https的ssl认证//发起请求 , 调用trustAll()方法返回的clientHttpEntity entity = trustAll().execute(request).getEntity();return EntityUtils.toString(entity, "UTF-8");} catch (Exception e) {throw new RuntimeException(e);} finally {
// httpClient.close();}}private static List<String> extractDataByTag(String html, String tagName, String className) {List<String> dataList = new ArrayList<>();Document doc = Jsoup.parse(html);Elements elements = doc.select(String.format(".%s", className));for (Element element : elements) {String data = element.select(tagName).text();dataList.add(data);}return dataList;}public static CloseableHttpClient trustAll(){//配置,发送https请求时,忽略ssl证书认证(否则会报错没有证书)SSLContext sslContext = null;try {sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {@Overridepublic boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {return true;}}).build();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (KeyManagementException e) {e.printStackTrace();} catch (KeyStoreException e) {e.printStackTrace();}//创建httpClientCloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).setSSLHostnameVerifier(new NoopHostnameVerifier()).build();return client;}
}
2. urlconnection忽略ssl证书连接
忽略HTTPS请求的SSL证书,必须在openConnection之前调用
package com.neo.address.parse;import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;/*** Description: httpclient跳过https验证*/import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;import org.apache.commons.io.IOUtils;/*** created by liu on 2020/03/18 14:23*/public class SslUtil {private static void trustAllHttpsCertificates() throws Exception {TrustManager[] trustAllCerts = new TrustManager[1];TrustManager tm = new miTM();trustAllCerts[0] = tm;SSLContext sc = SSLContext.getInstance("SSL");sc.init(null, trustAllCerts, null);HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());}static class miTM implements TrustManager, X509TrustManager {public X509Certificate[] getAcceptedIssuers() {return null;}public boolean isServerTrusted(X509Certificate[] certs) {return true;}public boolean isClientTrusted(X509Certificate[] certs) {return true;}public void checkServerTrusted(X509Certificate[] certs, String authType)throws CertificateException {return;}public void checkClientTrusted(X509Certificate[] certs, String authType)throws CertificateException {return;}}/*** 忽略HTTPS请求的SSL证书,必须在openConnection之前调用** @throws Exception*/public static void ignoreSsl() throws Exception {HostnameVerifier hv = new HostnameVerifier() {public boolean verify(String urlHostName, SSLSession session) {System.out.println("Warning: URL Host: " + urlHostName+ " vs. " + session.getPeerHost());return true;}};trustAllHttpsCertificates();HttpsURLConnection.setDefaultHostnameVerifier(hv);}
}