为什么android会得到错误的ssl证书? (两个域,一个服务器)

时间:2014-02-22 15:58:25

标签: android ssl nginx androidhttpclient

我有两个域:foo.netbar.com。它们都具有SSL证书,并且在所有桌面和移动浏览器中都能很好地运行。它们托管在使用nginx配置的同一台服务器上。

但是,当我从本机Android应用程序中向域发出请求时,它会以某种方式从错误的域获取证书!这会导致IO异常:

request = new HttpPost("https://foo.net/api/v1/baz");
request.setHeader("Authorization", "user:pass");
response = httpClient.execute(request);

...

  

javax.net.ssl.SSLException: hostname in certificate didn't match: <foo.net> != <bar.com> OR <bar.com> OR <www.bar.com>

当其他所有措施似乎表明服务器配置正确时,会导致android / java尝试使用bar.com中的证书? nginx访问或错误日志中没有任何内容。我的android项目中没有提到bar.com

编辑:我不确定原因,但似乎服务器正在使用bar.com证书作为服务器IP https://198.245.xx.xxx

3 个答案:

答案 0 :(得分:27)

此问题的最可能原因是服务器使用Server Name Indication来选择要发送的证书。如果客户端不支持SNI,则服务器无法选择在SSL / TLS握手期间(在发送任何HTTP流量之前)要发送的证书。当您想在同一个IP地址和端口上使用多个证书时,需要SNI,但并非所有客户端都支持它(众所周知,任何版本的Windows XP上的IE,以及许多移动浏览器)。

你也明显地使用Apache HTTP Client库(而不是HttpsURLConnectionthere can be SNI support with some Android versions。 支持Apache HTTP客户端库is quite recent中的SNI,当然还没有进入Android堆栈。

您可能会发现the workaround described in this article很有用(虽然它似乎只适用于Android 4.2 +)。

另外两个选项是:

  • 为每个主机使用不同的IP地址(以便不需要SNI),如果您控制服务器,或
  • 使用其他HTTP客户端库(例如HttpsURLConnection)。

答案 1 :(得分:2)

Apache的解决方案,更像是一个技巧: 根据/ etc / apache2 / sites-enabled中的vhost名称加载SSL证书。因此,要检查该检查,请确保首先加载有问题的证书(请记住,vhosts是按名称加载的)。

答案 2 :(得分:0)

看起来foo.net的证书配置错误,并使用与bar.com相同的主机名

尝试运行在线证书验证工具,例如foo.net上的https://www.digicert.com/help/,以确定。

我认为您需要使用正确的主机名重新生成foo.net证书,或者重新配置ngix以确保nginx为正确的主机提供正确的证书。