java.io.IOException异常:主机名未验证 [英] java.io.IOException: Hostname was not verified

查看:363
本文介绍了java.io.IOException异常:主机名未验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从我的Andr​​oid应用程序连接到一个URL中的Andorid版本4.1.1,而我得到了我的问题的标题指出的错误,但是当我试图从版本的Andorid 4.0连接相同的URL。 4或3.1,一切工作正常。

在code片段:

 尝试{
        。
        。
        。
        网址URL =新的URL(urlStr);
        Log.i(TAG,[URL]+ urlStr);
        HttpURLConnection的康恩=(HttpURLConnection类)url.openConnection();
        INT大小= conn.getContentLength();
        INT响应code = conn.getResponse code();
        Log.d(TAG,响应code:+响应code);
        。
        。
        。
        }赶上(例外五){
        e.printStackTrace();
        }


私有静态无效trustAllHosts(){

        的TrustManager [] trustAllCerts =新的TrustManager [] {新X509TrustManager(){
            公共java.security.cert.X509Certificate [] getAcceptedIssuers(){
                    返回新java.security.cert.X509Certificate [] {};
            }

            公共无效checkClientTrusted(x509证书[]链,
                            字符串的authType)抛出CertificateException {
            }

            公共无效checkServerTrusted(x509证书[]链,
                            字符串的authType)抛出CertificateException {
            }
        }};

        尝试 {
                的SSLContext SC = SSLContext.getInstance(TLS);
                sc.init(NULL,trustAllCerts,新java.security.SecureRandom中的());
                HttpsURLConnection
                                .setDefaultSSLSocketFactory(sc.getSocketFactory());
        }赶上(例外五){
                的System.out.println(IOException异常:HTTPSRequest :: trustAllHosts);
                e.printStackTrace();
        }
    }
 

但在这里我清楚的一件事是,也许证书是自签名证书,不包括他们在密钥库中。

我不明白为什么这excepton occure只能在Android的Verison 4.1.1操作系统 谢谢你。

FULL堆栈跟踪

  10月1日至31号:26:08.348:W / System.err的(3158):java.io.IOException异常:主机名<网址>未验证
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.connect(HttpsURLConnectionImpl.java:446)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:130)
10月1号至三十一号:26:08.348:W / System.err的(3158):在java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
10月1号至三十一号:26:08.348:W / System.err的(3158):在java.net.URLConnection.getContentLength(URLConnection.java:316)
10月1号至三十一号:26:08.348:W / System.err的(3158):在libcore.net.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:191)
10月1号至三十一号:26:08.348:W / System.err的(3158):在com.ih.util.HelpVideoServices $ downloadTask.run(HelpVideoServices.java:172)
 

解决方案

在你使用证书运行的情况下,这并不意味着什么,你想绕过他们,你还需要添加一个空的主机名验证,使这个code工件

  HttpsURLConnection.setDefaultHostnameVerifier(新NullHostNameVerifier());
的SSL连接上下文= SSLContext.getInstance(TLS);
context.init(NULL,新X509TrustManager [] {新NullX509TrustManager()},新的SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
 

而code主机:

 进口javax.net.ssl​​.HostnameVerifier;
进口javax.net.ssl​​.SSLSession中;

公共类NullHostNameVerifier实现的HostnameVerifier {

    @覆盖
    公共布尔验证(字符串主机名,的SSLSession会话){
        Log.i(RestUtilImpl+主机的批准证书);
        返回true;
    }

}
 

这需要运行一次,但如果你正在改变您的连接对象,你可能需要再次运行它。

I am trying to connect to a URL from a my Android app in Andorid Version 4.1.1, and I get the error indicated in the Title of my question, but when I tried to connect the same URL from Andorid Version 4.0.4 or 3.1, all works fine.

The Code fragment :

    try {
        .
        .
        .
        URL url = new URL(urlStr);
        Log.i(TAG,"[ URL ] " + urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        int size = conn.getContentLength();
        int responsecode = conn.getResponseCode();
        Log.d(TAG, "Responsecode: " + responsecode);
        .
        .
        .
        } catch (Exception e) {
        e.printStackTrace();
        }


private static void trustAllHosts() {

        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[] {};
            }

            public void checkClientTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
            }
        } };

        try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection
                                .setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
                System.out.println("IOException : HTTPSRequest::trustAllHosts");
                e.printStackTrace();
        }
    }

But here i clear one thing is that "Maybe certificate is that self-signed certificates and is not including them in a KeyStore.

I do not understand why this excepton occure only in Android Verison 4.1.1 OS Thanks.

FULL STACK TRACE

01-31 10:26:08.348: W/System.err(3158): java.io.IOException: Hostname <URL> was not verified
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:446)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:273)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:130)
01-31 10:26:08.348: W/System.err(3158):     at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
01-31 10:26:08.348: W/System.err(3158):     at java.net.URLConnection.getContentLength(URLConnection.java:316)
01-31 10:26:08.348: W/System.err(3158):     at libcore.net.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:191)
01-31 10:26:08.348: W/System.err(3158):     at com.ih.util.HelpVideoServices$downloadTask.run(HelpVideoServices.java:172)                                

解决方案

In case you are running with certificates that doesn't mean anything and you want to bypass them you also need to add a null host name verifier to make this code work

HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new X509TrustManager[]{new NullX509TrustManager()}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

And the code for the host:

import javax.net.ssl.HostnameVerifier ;
import javax.net.ssl.SSLSession;

public class NullHostNameVerifier implements HostnameVerifier {

    @Override   
    public boolean verify(String hostname, SSLSession session) {
        Log.i("RestUtilImpl", "Approving certificate for " + hostname);
        return true;
    }

}

This needs to run once, but if you are making changes to your connection object you might need to run it again.

这篇关于java.io.IOException异常:主机名未验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆