我有两个域:foo.net
和 bar.com
.它们都有 SSL 证书,并且在所有桌面和移动浏览器中都能正常工作。它们托管在使用 nginx 配置的同一台服务器上。
但是,当我从 native 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 访问或错误日志中没有出现任何内容。没有提到bar.com
在我的 android 项目中的任何地方。
编辑:我不知道为什么,但似乎服务器正在使用 bar.com
的证书服务器 IP https://198.245.xx.xxx
最佳答案
这个问题最可能的原因是服务器使用了Server Name Indication选择要发送的证书。如果客户端不支持 SNI,则服务器无法选择在 SSL/TLS 握手期间(在发送任何 HTTP 流量之前)发送哪个证书。当您想在同一个 IP 地址和端口上使用多个证书时需要 SNI,但并非所有客户端都支持它(众所周知,任何版本的 Windows XP 上的 IE 和许多移动浏览器)。
您还明显地使用了 Apache HTTP 客户端库(不是 HttpsURLConnection
,there can be SNI support with some Android versions 。
Apache HTTP 客户端库中对 SNI 的支持 is quite recent ,当然还没有进入 Android 堆栈。
您可能会发现 the workaround described in this article有用(虽然它似乎只适用于 Android 4.2+)。
另外两个选项是:
- 为每个主机使用不同的 IP 地址(这样就不需要 SNI),如果您可以控制服务器,或者
- 使用另一个 HTTP 客户端库(例如
HttpsURLConnection
)。
关于android - 为什么android会得到错误的ssl证书? (两个域,一台服务器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21956663/