java 为什么 HttpUrlConnection 在移动数据连接上抛出 SSLException?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12885247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is HttpUrlConnection throwing an SSLException while on a mobile data connection?
提问by acj
When using Android's HttpUrlConnection
library to make an HTTPS request, I sometimes see the following exception being thrown:
在使用 Android 的HttpUrlConnection
库发出 HTTPS 请求时,我有时会看到抛出以下异常:
javax.net.ssl.SSLException: SSL handshake aborted: ssl=0x5c1b18a0: I/O error during system call, Connection reset by peer
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:395)
...
After digging into the issue a bit, I've learned that
在深入研究这个问题之后,我了解到
- Everything works fine on wifi
- The exception is only thrown when the device is on a mobile data connection
- After making an HTTPS over wifi first, connecting over mobile data tends to work fine for a while
- The problem appears to happen on a small number of specific mobile carriers
- 在 wifi 上一切正常
- 仅当设备处于移动数据连接时才会抛出异常
- 在首先通过 wifi 创建 HTTPS 后,通过移动数据连接往往可以正常工作一段时间
- 该问题似乎发生在少数特定移动运营商上
What could be happening? Are some mobile carriers interfering with HTTPS traffic?
会发生什么?某些移动运营商是否会干扰 HTTPS 流量?
回答by acj
Short answer:
简短的回答:
It turns out that some mobile carriers will return an IP address for DNS lookups that should have failed as non-existent. The server that the app was connecting to would fail to resolve sometimes, and the carrier would try to assist by providing a page of similar sites.
事实证明,一些移动运营商会返回一个 IP 地址用于 DNS 查找,而这些 IP 地址本应因不存在而失败。应用程序连接的服务器有时会无法解析,运营商会尝试通过提供类似网站的页面来提供帮助。
Longer answer:
更长的答案:
The hostname for the server that my app was connecting to would sometimes fail to resolve. This would normally throw an UnknownHostException
to indicate the DNS failure. I expect this to happen occasionally, and the app handles it. The SSLException
was an anomaly.
我的应用程序连接到的服务器的主机名有时无法解析。这通常会抛出一个UnknownHostException
指示 DNS 故障。我希望这种情况偶尔会发生,并且应用程序会处理它。这SSLException
是一个异常。
On carriers that intercept failed DNS lookups, navigating a Web browser to a non-existent host will show a page of "search results" that aim to help you find what you were looking for. (Some DLS/cable ISPs do this, too.) For an app making an HTTPS request, though, this breaks the SSL handshake because the remote host is different from what the app is expecting.
在拦截失败的 DNS 查找的运营商上,将 Web 浏览器导航到不存在的主机将显示一个“搜索结果”页面,旨在帮助您找到所需的内容。(一些 DLS/有线 ISP 也这样做。)但是,对于发出 HTTPS 请求的应用程序,这会中断 SSL 握手,因为远程主机与应用程序期望的不同。
The root cause was a misbehaving DNS server that would return a non-existent host error for one of the servers that my app was using. Connecting over wifi seemed to be more reliable (due to another quirk of the same DNS server). Connecting over wifi would allow the DNS entry to be cached, thus temporarily masking the problem when we would subsequently connect over a mobile data connection. Most of the time, though, the mobile carrier would intercept the failed DNS lookup and redirect us to an unexpected hostname, which resulted in a failed SSL handshake.
根本原因是 DNS 服务器行为不当,它会为我的应用程序使用的其中一台服务器返回不存在的主机错误。通过 wifi 连接似乎更可靠(由于同一 DNS 服务器的另一个怪癖)。通过 wifi 连接将允许缓存 DNS 条目,从而在我们随后通过移动数据连接进行连接时暂时掩盖问题。但是,在大多数情况下,移动运营商会拦截失败的 DNS 查找并将我们重定向到意外的主机名,从而导致 SSL 握手失败。