Java异常处理006:SSL证书异常:SSLHandshakeException: sun.security.validator.ValidatorException
本地请求第三方接口,出现如下异常
javax.net.ssl.SSLHandshakeException: 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.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1514) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026) at sun.security.ssl.Handshaker.process_record(Handshaker.java:961) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
异常原因
本地没有可用的证书,导致SSL校验失败
解决方案
- 安装正数
- 通过代码方式忽略证书(可以临时用,不推荐长期使用,存在安全性问题)
方案2 源码如下
1- 工具类
package com.hs.util; /* * *@Description: *@Author:TYJ *@Date: create in 2020/4/22 18:18 */ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class SslUtils { 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() {
//实现自己的脚丫逻辑,这里就直接返回true,不进行校验 public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); } }
2-URL请求封装
package com.hs.util; /* * *@Description: *@Author:TYJ *@Date: create in 2020/4/22 18:21 */ import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import org.apache.commons.io.IOUtils; public class SslTest { public String getRequest(String url,int timeOut) throws Exception{ URL u = new URL(url); if("https".equalsIgnoreCase(u.getProtocol())){ SslUtils.ignoreSsl(); } URLConnection conn = u.openConnection(); conn.setConnectTimeout(timeOut); conn.setReadTimeout(timeOut); return IOUtils.toString(conn.getInputStream()); } public String postRequest(String urlAddress,String args,int timeOut) throws Exception{ URL url = new URL(urlAddress); if("https".equalsIgnoreCase(url.getProtocol())){ SslUtils.ignoreSsl(); } URLConnection u = url.openConnection(); u.setDoInput(true); u.setDoOutput(true); u.setConnectTimeout(timeOut); u.setReadTimeout(timeOut); OutputStreamWriter osw = new OutputStreamWriter(u.getOutputStream(), "UTF-8"); osw.write(args); osw.flush(); osw.close(); u.getOutputStream(); return IOUtils.toString(u.getInputStream()); } public static void main(String[] args) { try { SslTest st = new SslTest(); String result = st.getRequest("https://www.baidu.com/", 3000); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } } }
END