Java Apache Http绕过Https证书校验:PKIX failed: SunCertPathBuilderException:unable to find valid certificat
Java Apache Http绕过Https证书校验:PKIX failed: SunCertPathBuilderException:unable to find valid certificat
·
Java Apache Http报错信息
在本地项目用ApacheHttp请求demo的时候报错:
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:456)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:323)
at sun.security.validator.Validator.validate(Validator.java:271)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:315)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:223)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
... 25 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:451)
... 31 common frames omitted
Exception in thread "main" java.lang.RuntimeException: error
Java Apache Http实例代码
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Map;
public enum HttpUtilDemo {
;
private static final Logger logger = LoggerFactory.getLogger(HttpUtilDemo.class);
/**
* setConnectTimeout: 从客户端到url建立连接的超时时间
*/
private static final int CONNECT_TIMEOUT = 30 * 1000;
/**
* setSocketTimeout: 连接上一个url后,获取response的返回等待时间
*/
private static final int SOCKET_TIMEOUT = 3600 * 1000;
public static JSONObject postHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
CookieStore cookieStore = new BasicCookieStore();
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setDefaultCookieStore(cookieStore)
.build()) {
HttpPost post = new HttpPost(URL);
// UTF-8 解决中文乱码
StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
post.addHeader("content-type", "application/json; charset=UTF-8");
post.addHeader("Accept", "application/json");
post.addHeader("Accept-Encoding", "UTF-8");
post.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");
if (!CollectionUtils.isEmpty(headerMap)) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
post.setEntity(params);
// 发送 post 请求
HttpResponse response = httpClient.execute(post);
if (response == null) {
throw new RuntimeException("response is null");
} else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String lines;
StringBuilder responseMsg = new StringBuilder("");
while ((lines = reader.readLine()) != null) {
lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
responseMsg.append(lines);
}
reader.close();
in.close();
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", responseMsg.toString());
// save header
for (String name : headerName) {
jsonObject.put(name, response.getHeaders(name));
}
return jsonObject;
} else {
throw new RuntimeException("response status is not 200");
}
} catch (Exception ex) {
logger.error("", ex);
throw new RuntimeException("error");
}
}
}
问题代码片段
这里的代码有问题,需要开启绕过SSL的认证。
新增绕过https(SSL)认证
/**
* 绕过https证书校验
*/
public static HttpClientBuilder createSSLClientDefaultBuilder() {
HttpClientBuilder httpClientBuilder = null;
try {
SSLContextBuilder builder = new SSLContextBuilder();
// 实现该接口,证书受信任的X509证书校验为true
builder.loadTrustMaterial(null, (chain, authType) -> true);
// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
// HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
httpClientBuilder = HttpClients.custom().setSSLSocketFactory(socketFactory);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("系统异常");
}
return httpClientBuilder;
}
Http工具修改后代码参考:
public enum HttpUtil {
;
private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);
/**
* setConnectTimeout: 从客户端到url建立连接的超时时间
*/
private static final int CONNECT_TIMEOUT = 30 * 1000;
/**
* setSocketTimeout: 连接上一个url后,获取response的返回等待时间
*/
private static final int SOCKET_TIMEOUT = 3600 * 1000;
public static JSONObject postHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
CookieStore cookieStore = new BasicCookieStore();
// 默认是 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
try (CloseableHttpClient httpClient = createSSLClientDefaultBuilder()
.setDefaultRequestConfig(requestConfig)
.setDefaultCookieStore(cookieStore)
.build()) {
HttpPost post = new HttpPost(URL);
// UTF-8 解决中文乱码
StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
post.addHeader("content-type", "application/json; charset=UTF-8");
post.addHeader("Accept", "application/json");
post.addHeader("Accept-Encoding", "UTF-8");
post.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");
if (!CollectionUtils.isEmpty(headerMap)) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
post.setEntity(params);
// 发送 post 请求
HttpResponse response = httpClient.execute(post);
if (response == null) {
throw new RuntimeException("response is null");
} else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String lines;
StringBuilder responseMsg = new StringBuilder("");
while ((lines = reader.readLine()) != null) {
lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
responseMsg.append(lines);
}
reader.close();
in.close();
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", responseMsg.toString());
// save header
for (String name : headerName) {
jsonObject.put(name, response.getHeaders(name));
}
return jsonObject;
} else {
throw new RuntimeException("response status is not 200");
}
} catch (Exception ex) {
logger.error("", ex);
throw new RuntimeException("error");
}
}
public static JSONObject getHttpJsonData(String URL, JSONObject requestJsonObject, Map<String, String> headerMap, String... headerName) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECT_TIMEOUT)
.setSocketTimeout(SOCKET_TIMEOUT)
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
CookieStore cookieStore = new BasicCookieStore();
try (CloseableHttpClient httpClient = createSSLClientDefaultBuilder()
.setDefaultRequestConfig(requestConfig)
.build()) {
HttpGet httpGet = new HttpGet(URL);
// UTF-8 解决中文乱码
StringEntity params = new StringEntity(requestJsonObject.toJSONString(), "UTF-8");
httpGet.addHeader("content-type", "application/json; charset=UTF-8");
httpGet.addHeader("Accept", "application/json");
httpGet.addHeader("Accept-Encoding", "UTF-8");
httpGet.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36");
if (!CollectionUtils.isEmpty(headerMap)) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpGet.addHeader(entry.getKey(), entry.getValue());
}
}
// 发送 httpGet 请求
HttpResponse response = httpClient.execute(httpGet);
if (response == null) {
throw new RuntimeException("response is null");
} else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String lines;
StringBuilder responseMsg = new StringBuilder("");
while ((lines = reader.readLine()) != null) {
lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
responseMsg.append(lines);
}
reader.close();
in.close();
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", responseMsg.toString());
// save header
for (String name : headerName) {
jsonObject.put(name, response.getHeaders(name));
}
return jsonObject;
} else {
throw new RuntimeException("response status is not 200");
}
} catch (Exception ex) {
logger.error("", ex);
throw new RuntimeException("error");
}
}
/**
* 绕过https证书校验
*/
public static HttpClientBuilder createSSLClientDefaultBuilder() {
HttpClientBuilder httpClientBuilder = null;
try {
SSLContextBuilder builder = new SSLContextBuilder();
// 实现该接口,证书受信任的X509证书校验为true
builder.loadTrustMaterial(null, (chain, authType) -> true);
// 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(builder.build(), new String[]{"TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
// HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。
httpClientBuilder = HttpClients.custom().setSSLSocketFactory(socketFactory);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("系统异常");
}
return httpClientBuilder;
}
}
请求示例
@Slf4j
public class RunTestDemo {
@SneakyThrows
public static void main(String[] args) {
// 先登录获取token
String url = "https://login.xxxx/login";
JSONObject request = new JSONObject();
request.put("password", "xxx");
JSONObject object = HttpUtil.postHttpJsonData(url, request, null, "Set-Cookie");
Map<String, String> headerMap = new HashMap<>();
Header[] headers = (Header[]) object.get("Set-Cookie");
headerMap.put("Cookie", headers[0].getValue());
// 请求目标https
String url2 = "https://xxxxxxx";
JSONObject request2 = new JSONObject();
request2.put("password", "xxxx");
headerMap.put("requested", "xxxxx");
JSONObject object2 = HttpUtil.postHttpJsonData(url2, request2, headerMap);
log.info(object2.toJSONString());
}
}
更多推荐
所有评论(0)