javax.net.ssl.sslhandshakeException:sun.security.validator.validatorException:PKIX path buildind failed
前段时间开发的一个需求,需要通过图片URL获取图片的base64编码,测试的时候使用的是百度图片的url,测试没有问题,但是发布后测试时报如下错:
javax.net.ssl.sslhandshakeException:sun.security.validator.validatorException:PKIX path buildind failed
报错代码:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.Base64; public class Base64Util { private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); public static String getBase64ByUrl(String urlPath){ ByteArrayOutputStream data = new ByteArrayOutputStream(); try { URL url = new URL(urlPath); byte[] by = new byte[1024]; URLConnection urlConnection = url.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; httpURLConnection.setConnectTimeout(1000*5); httpURLConnection.connect(); InputStream inputStream = httpURLConnection.getInputStream(); int len = -1; while ( (len = inputStream.read(by)) !=-1){ data.write(by,0,len); } inputStream.close(); } catch (Exception e) { logger.error("获取图片base64出错:" + e + ",图片url为:" + urlPath); } return Base64.getMimeEncoder().encodeToString(data.toByteArray()); } }
检查发现是jdk的证书库里并没有将该站点的证书作为受信任的安全证书,只要在打开链接的时候设置忽略证书检查就可以解决,更新代码如下:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.Base64; public class Base64Util { private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); public static String getBase64ByUrl(String urlPath){ ByteArrayOutputStream data = new ByteArrayOutputStream(); try { HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; URL url = new URL(urlPath); byte[] by = new byte[1024]; //忽略证书信任 trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); URLConnection urlConnection = url.openConnection(); HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection; httpURLConnection.setConnectTimeout(1000*5); httpURLConnection.connect(); InputStream inputStream = httpURLConnection.getInputStream(); int len = -1; while ( (len = inputStream.read(by)) !=-1){ data.write(by,0,len); } inputStream.close(); } catch (Exception e) { logger.error("获取图片base64出错:" + e + ",图片url为:" + urlPath); } return Base64.getMimeEncoder().encodeToString(data.toByteArray()); } private static void trustAllHttpsCertificates() throws Exception { javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; javax.net.ssl.TrustManager tm = new miTM(); trustAllCerts[0] = tm; javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext .getInstance("SSL"); sc.init(null, trustAllCerts, null); javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc .getSocketFactory()); } static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted( java.security.cert.X509Certificate[] certs) { return true; } public boolean isClientTrusted( java.security.cert.X509Certificate[] certs) { return true; } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } } }
在URLConnection urlConnection = url.openConnection();之前忽略证书信任,问题解决。