为什么HttpUrlConnection在移动数据连接上抛出SSLException?

acj*_*acj 18 java ssl android android-networking

当使用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)
...
Run Code Online (Sandbox Code Playgroud)

在深入研究这个问题之后,我已经了解到了这一点

  • 无线网络上一切正常
  • 仅当设备处于移动数据连接时才会抛出异常
  • 在首先通过wifi进行HTTPS之后,通过移动数据进行连接往往会在一段时间内正常工作
  • 问题似乎发生在少数特定的移动运营商身上

可能会发生什么?某些移动运营商是否会干扰HTTPS流量?

acj*_*acj 20

简短回答:

事实证明,一些移动运营商将返回一个IP地址,用于DNS查找应该已经失败的IP地址.应用程序连接的服务器有时无法解决,运营商会尝试通过提供类似网站的页面来提供帮助.


更长的回答:

我的应用程序连接到的服务器的主机名有时无法解析.这通常会抛出一个UnknownHostException指示DNS故障.我希望偶尔会发生这种情况,应用程序会处理它.这SSLException是一个异常现象.

在拦截失败的DNS查找的运营商上,将Web浏览器导航到不存在的主机将显示一个"搜索结果"页面,旨在帮助您找到所需内容.(一些DLS /有线ISP也这样做.)但是,对于发出HTTPS请求的应用程序,这会破坏SSL握手,因为远程主机与应用程序的期望不同.

根本原因是一个行为不当的DNS服务器,它会为我的应用程序正在使用的其中一个服务器返回一个不存在的主机错误.通过wifi连接似乎更可靠(由于同一DNS服务器的另一个怪癖).通过wifi连接将允许缓存DNS条目,从而在我们随后通过移动数据连接进行连接时暂时屏蔽该问题.但是,大多数情况下,移动运营商会拦截失败的DNS查找并将我们重定向到意外的主机名,从而导致SSL握手失败.

  • 虽然确实根本原因是连接提供者,但我认为重新解释这个问题会使其在相同情况下不易被其他人发现.当我第一次遇到这个问题时(也就是说,在我知道这是一个软DNS故障之前),我会问这个问题. (6认同)
  • 如何在应用程序中处理它? (3认同)
  • @acj知道谷歌是什么问题的一半. (2认同)