Java SSLException:证书中的主机名不匹配。非常错误的证书?

问题描述:

我在为我的服务器通过互联网同步数据的android写简单的记事本。我使用https和startssl的免费证书,一切都很顺利。后来,我用自己的SSL证书添加了新的虚拟主机,并且我的应用程序突然停止了服务器。它抛出:Java SSLException:证书中的主机名不匹配。非常错误的证书?

javax.net.ssl.SSLException: hostname in certificate didn't match: <www.rapidnote.emendus.ovh> != <othersite.emendus.ovh> OR <othersite.emendus.ovh> OR <emendus.ovh> 

它试图验证从不同的apache虚拟主机完全不同的证书。我对rapidnote虚拟主机Apache的配置是:

<VirtualHost *:80> 
    ServerName    rapidnote.emendus.ovh 
    ServerAlias    www.rapidnote.emendus.ovh 
    Redirect Permanent  / https://www.rapidnote.emendus.ovh 
</VirtualHost> 

<VirtualHost *:443> 
    ServerName    rapidnote.emendus.ovh 
    DocumentRoot    /var/www/rapidnote 
    SSLEngine     on 
    SSLCertificateFile  cert_location/rapidnote.emendus.ovh.crt 
    SSLCertificateKeyFile  key_location/rapidnote.emendus.ovh.key 
    SSLCertificateChainFile cert_location/sub.class1.server.ca.pem 
</VirtualHost> 

<VirtualHost *:443> 
    ServerName    www.rapidnote.emendus.ovh 
    DocumentRoot    /var/www/rapidnote 
    SSLEngine     on 
    SSLCertificateFile  cert_location/www.rapidnote.emendus.ovh.crt 
    SSLCertificateKeyFile  key_location/www.rapidnote.emendus.ovh.key 
    SSLCertificateChainFile cert_location/sub.class1.server.ca.pem 
</VirtualHost> 

我的代码看起来如下:

HttpClient httpClient = new DefaultHttpClient(); 
HttpPost  httpPost = new HttpPost("https://www.rapidnote.emendus.ovh/" + paramScriptName); 
HttpResponse response = httpClient.execute(httpPost); 

如果我在apache的关闭othersite.emendus.ovh虚拟主机,然后异常SSLException消息称:

<www.rapidnote.emendus.ovh> != <rapidnote.emendus.ovh> OR <rapidnote.emendus.ovh> OR <emendus.ovh> 

如果然后我将"https://www.rapidnote.emendus.ovh/"更改为"https://rapidnote.emendus.ovh/",它开始工作。我检查了两个(www和非www)证书和两个公共名称都是正确的。 我觉得应该验证,我给了他HttpPost构造从我的服务器,而不是一些其他随机证书域的证书......

我使用了一些测试网站,以验证我的SSL配置和它说,它是所有罚款。

一切都发生在android 4.2.2 (API 17)。 我构建的应用程序与min SDK 14target SDK API 20 Android 4.4 (KitKat Wear)

我怎么能告诉他核实无误的证书,此域指定? 是在应用程序或Apache的网站上的问题?

+0

为什么不将所有:80个请求和:443个www请求重定向到单个443 rapidnote.emendus.ovh地址,而不是尝试使用单个SSL来涵盖多个端点? – 2014-10-20 23:20:20

+1

由于SSL验证在重定向之前发生,所以它会失败并在开始时停止。 – Dzarafata 2014-10-21 08:47:35

您的服务器配置为使用服务器名称指示(SNI)显示不同的证书。

据我所知,与Android捆绑在一起的Apache HTTP Client版本不支持SNI。您可以尝试使用HttpsURLConnection而不是HttpClient,这应该支持Android版本不太旧的SNI。 the answers to this question有更多详细信息。

请注意,您仍然需要证书显示主机名称对该主机名有效,即它需要该名称的主题备用名称条目(或主题DN的CN需要如果没有DNS SAN,就是该名称)。 (如果您有这样的证书,也可以使用通配符。)

+0

谢谢!它正在工作;) – Dzarafata 2014-10-21 09:57:11

SSL证书通过IP地址而不是域名查找。

因此,检查证书时,第一项是赢了,而你的情况是一个:rapidnote.emendus.ovh

如果您切换周围的条目,该条目www.rapidnote.emendus.ovh会工作,而不是其他。

我认为有一种方法可以让www和非www域名在一个证书上工作,但我不记得确切的过程,对不起。希望有人会填写这些细节,我们都会学习。我认为一些CA会给你两个地址,但是我不知道他们是如何制作该证书的。

如果您只需要使用一个IP地址,我建议您查看通配符和通用通信证书。

如果您可以有多个IP地址,则为每个网址分配一个不同的IP地址。但是,由于您直接使用80/433,因此这看起来像生产服务器。这建议不是超级推荐。我喜欢为我的www和非www网址提供一个IP地址。

+0

我正在使用SNI在一个IP上使用多个CA,每个域名使用一个,并且使用webbrowser完美无瑕,但是就像Bruno所说的,似乎Android的Apache HTTp客户端不支持SNI。 – Dzarafata 2014-10-21 08:50:33