Android主机名未经过验证。如何允许所有主机?

时间:2014-11-09 17:28:08

标签: java android httpurlconnection

我正在尝试从以HTTPS开头的网址获取图片。我一直得到Hostname未经验证的异常。

我看了一下这个问题java.io.IOException: Hostname was not verified,但没有理解如何让它发挥作用。

有什么方法可以允许所有主机名吗?

这里的代码给了我麻烦:

public Drawable drawableFromUrl(String url) {
    Bitmap x;
    HttpURLConnection connection;
    try {
        connection = (HttpURLConnection) new URL(url).openConnection();
        connection.connect();
        InputStream input = connection.getInputStream();
        x = BitmapFactory.decodeStream(input);
        return new BitmapDrawable(x);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        return null;
    }
    return null;
}

提前感谢您的帮助

1 个答案:

答案 0 :(得分:0)

当TLS证书是自签名证书或证书上的域与服务器的主机名不匹配时,会发生此错误。

This answer提供了完整的解决方案:

/**
 * Disables the SSL certificate checking for new instances of {@link HttpsURLConnection} This has been created to
 * aid testing on a local box, not for use on production.
 */
private static void disableSSLCertificateChecking() {
    TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {

            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
                // not implemented
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
                // not implemented
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

        }
    };

    try {

        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }

        });
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

在进行第一次HTTPS连接之前,只需运行一次即可。但是,如果您控制服务器,则最好尝试获取有效的证书。