得到'IOException:主机名未经过验证',虽然主机名(IP地址)与通用名称相匹配

时间:2015-02-27 08:40:35

标签: java android ssl okhttp

在成功插入证书后,我如何获得IOException: hostname was not verified,并将其作为OKHttp的SSLFactory实例的一部分使用?我知道这是自签名证书的常见问题,但前提是服务器上的名称与证书上的名称不匹配。在我的例子中,异常消息显示地址,然后是CN,它们完全匹配。

我通过提供一个超级宽容的主机验证器暂时解决了这个问题:

this.client.setHostnameVerifier(new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        //TODO: Make this more restrictive
        return true;
    }
});

但它仍然感觉很奇怪。你能告诉我可能导致这个问题的原因吗?或者,至少,您认为什么是更具限制性的处理程序?我想,一个尝试从会话中提取主机名,并与hostname参数进行比较。

更新: 这是请求的堆栈跟踪。出于隐私原因,我无法透露任何数据,但请记住主机名IP,以及CN匹配1:1。

java.io.IOException: Hostname xxx.xxx.xxx.xxx not verified:
certificate: sha1/xxxxxxxxxxxxxxxxxxxxxxxxx=
DN: xxx.xxx.xxx.xxx.xxx.xxx.xxx=#xxxxxxxxxxxxxxxxxxxxxxxxxxxxx,CN=xxx.xxx.xxx.xxx,OU=xxxxxx,O=xxxxxx,L=xxxxxx,ST=xxxxxx,C=xx
subjectAltNames: []
at com.squareup.okhttp.Connection.upgradeToTls(Connection.java:260)
at com.squareup.okhttp.Connection.connect(Connection.java:158)
at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:174)
at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:120)
at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:131)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:312)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:235)
at com.squareup.okhttp.Call.getResponse(Call.java:262)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:219)
at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192)
at com.squareup.okhttp.Call.execute(Call.java:79)

1 个答案:

答案 0 :(得分:0)

  

主机名xxx.xxx.xxx.xxx未经过验证

看起来您正在连接到IP地址。 IP的匹配行为在实现之间有所不同,但是为RFC2818(https)定义的检查要求IP地址位于主题备用名称部分(RFC2818, page 4)中:

  

在某些情况下,URI被指定为IP地址而不是a       主机名。在这种情况下,必须存在iPAddress subjectAltName       在证书中,必须与URI中的IP完全匹配。

实现之间的实际行为有所不同。有些人认为IP是CN,有些则不是。有些实现了正确的行为以要求IP作为类型iPAddress,而其他人则期望它作为类型dNSName。所以你最好把它作为CN,另外在主题替代名称部分中作为iPAdress和dNSName :(