为什么android会得到错误的ssl证书?(两个域,一台服务器) [英] Why does android get the wrong ssl certificate? (two domains, one server)

查看:17
本文介绍了为什么android会得到错误的ssl证书?(两个域,一台服务器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two domains: foo.net and bar.com. They both have SSL certificates, and they work well in all desktop and mobile browsers. They are hosted on the same server configured with nginx.

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

However, when I make a request to a domain from within a native android app, it somehow gets the certificate from the wrong domain! This results in an IO Exception:

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

...

javax.net.ssl.SSLException: 证书中的主机名不匹配:<foo.net>!=

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

What would cause android/java to try using the certificate from bar.com when every other measure seems to indicate that the server is correctly configured? Nothing appears in the nginx access or error log. There is no mention of bar.com anywhere in my android project.

我不知道为什么,但似乎服务器正在使用 bar.com 的证书作为服务器 IP https://198.245.xx.xxx

I'm not sure why, but it appears that the server is using the certificate for bar.com for the server IP https://198.245.xx.xxx

推荐答案

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

The most likely cause for this problem is that the server uses Server Name Indication to choose which certificate to send. If the client doesn't support SNI, the server cannot choose which certificate to send during the SSL/TLS handshake (before any HTTP traffic is sent). SNI is required when you want to use multiple certificates on the same IP address and port, but not all clients support it (notoriously, IE on any version of Windows XP, and a number of mobile browsers).

您还明显使用了 Apache HTTP 客户端库(不是 HttpsURLConnection,对于它可以有某些 Android 版本支持 SNI.Apache HTTP 客户端库中对 SNI 的支持是最近的,而且肯定没有't 进入了 Android 堆栈.

You're also visibly using the Apache HTTP Client library (not HttpsURLConnection, for which there can be SNI support with some Android versions. Support for SNI in the Apache HTTP Client library is quite recent, and certainly hasn't made it into the Android stack.

您可能会找到本文中描述的解决方法文章很有用(虽然它似乎只适用于 Android 4.2+).

You may find the workaround described in this article useful (although it seems only to work for Android 4.2+).

另外两个选项是:

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

这篇关于为什么android会得到错误的ssl证书?(两个域,一台服务器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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