• 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();之前忽略证书信任,问题解决。

  • 相关阅读:
    Linux文件系统之INode
    手写Netty之多路复用Select小案例
    多路复用器Select、Poll、Epoll区别梳理
    NAT模式、路由模式、桥接模式的区别
    Netty编解码器(理论部分)
    Netty之Unpooled_Bytebuf
    为什么 TCP 协议有粘包问题
    IDEA_2019.1版本中Protobuf的使用
    Netty服务端Server代码说明
    Netty之ChannelHandler
  • 原文地址:https://www.cnblogs.com/jxxblogs/p/13201437.html
Copyright © 2020-2023  润新知