我正在编写简单的记事本,用于通过互联网与我的服务器同步数据的android。我使用了来自startssl的https和免费证书,一切顺利。后来我用它自己的ssl证书添加了新的虚拟主机,我的应用程序突然停止了对服务器的连接。它抛出:
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 14
和target SDK API 20 Android 4.4 (KitKat Wear)
如何告诉他验证为此域名指定的正确证书? 是应用程序或apache网站上的问题吗?
答案 0 :(得分:5)
您的服务器配置为使用服务器名称指示(SNI)显示不同的证书。
据我所知,与Android捆绑在一起的Apache HTTP Client版本不支持SNI。您可以尝试使用HttpsURLConnection
代替HttpClient
,这应该支持Android版本中不太旧的SNI。 the answers to this question中有更多详细信息。
请注意,您仍然需要为主机名提供的证书对该主机名有效,即它需要该名称的主题备用名称条目(或者主题DN的CN需要是如果没有DNS SAN,则为该名称。 (如果您有这样的证书,也可以使用通配符。)
答案 1 :(得分:0)
SSL证书由IP地址而非域名查找。
因此,在检查证书时,第一个条目是获胜的条目,在您的情况下是:rapidnote.emendus.ovh
如果您改变了条目,www.rapidnote.emendus.ovh条目将起作用,而不是另一条。
我认为有一种方法可以让www和非www域名在一个证书上工作,但我无法记住确切的过程,抱歉。希望有人会填写这些细节,我们都会学习。我认为有些CA会给你这两个地址,但我又不确定他们是如何制作这个证书的。
如果您只需要使用一个IP地址,我建议您查看通配符和通用通信证书。
如果您可以拥有多个IP地址,请为每个网址分配不同的IP地址。但这确实看起来像生产服务器,因为您直接使用80/433。这个建议不是超级推荐的。我喜欢为我的www和非www网址提供一个IP地址。
答案 2 :(得分:0)
如果代码很大,并且您不想更改连接库,则解决方法是为每个VirtualHost设置不同的端口。这解决了我的问题。