乐趣区

关于java:No-subject-alternative-names-matching-IP-address-found

Java SSL 文件下载报错
需要:
筹备下载个文件, 是 https 的连贯, 浏览器没有问题。查看了下
org.apache.commons.io.FileUtils 工具类刚好有这个办法, 太省事了;

FileUtils.copyURLToFile(new URL(url), file);

果不其然报错了

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 47.114.190.241 found
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
    at java.net.URL.openStream(URL.java:1045)
    at org.apache.commons.io.FileUtils.copyURLToFile(FileUtils.java:1478)
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 47.114.190.241 found
    at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:168)
    at sun.security.util.HostnameChecker.match(HostnameChecker.java:94)
    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:200)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)

查看报错只须要批改 HostnameChecker 的 matchIP 办法就能够了
编写转换方法

 private URL transUrl(String urlStr) {
// 用于高版本 JDK 跳过证书验证
        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}

            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { }

            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}} };

        // Activate the new trust manager
        SSLContext sc = null;
        try {sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 用于校验 SSL 的 IP
            HostnameVerifier allHostsValid = new HostnameVerifier() {public boolean verify(String hostname, SSLSession session) {return true;}
            };
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
            // Open connection to the URL
            URL url = new URL(urlStr);
            URLConnection connection = url.openConnection();
            return connection.getURL();} catch (Exception e) {throw new RuntimeException(e);
        }
    }

从新编写下载的代码

FileUtils.copyURLToFile(transUrl(url), file);

问题解决了

退出移动版