我们在发请求时,会遇到需要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()方法返回的client
HttpEntity 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() {
@Override
public 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();
}
//创建httpClient
CloseableHttpClient 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);
}
}