WebViewClient 在重新创建片段时返回 "Couldn't establish a secure connection."
WebViewClient returning "Couldn't establish a secure connection." upon recreating the fragment
我们的应用程序有选项卡,其中一个片段可以包含一个 webviewclient。用户现在报告 webviewclient 无法加载页面的问题。我们已确认服务器已启动并且 运行,我们还确定该问题发生在 v4.3 和所有早期版本中。我们还确认它在 v5.0 中工作正常;现在我们无法测试它是否在 4.4 中工作(我想这些信息只有在有人知道 4.4 和更新版本中发生的更改会导致所有早期版本中出现故障时才有用)。
所以实际的问题是我们创建了 webviewclient 并将其加载到片段中,网页(通过 HTTPS 连接)在所有版本的这种情况下每次都能完美加载。对于 v5.0,我们可以单击不同的选项卡并返回到带有 webviewclient 的选项卡;我们可以看到正在创建的片段并且一切都按预期工作,网页按预期加载。但对于 v4.3 及更早版本,我们看到正在创建片段,但 webviewclient 触发 onReceivedError 并显示 -11 错误代码(无法建立安全连接)。进一步查看调试日志,我们得到一个握手错误,这是调用的日志。有趣的是,我们连接的网站可以接受 TLS1.2;我们可以看到,当我们使用 Firefox 进入 URL 并使用开发工具等时,这个错误也很有趣。
04-24 14:38:52.415: W/chromium(15434): external/chromium/net/http/http_stream_factory_impl_job.cc:865: [0424/143852:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant:
04-24 14:38:52.446: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:310: [0424/143852:INFO:ssl_client_socket_openssl.cc(310)] ssl_ctx_ is used
04-24 14:38:52.469: E/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:899: [0424/143852:ERROR:ssl_client_socket_openssl.cc(899)] handshake failed; returned 0, SSL error code 5, net_error -107
04-24 14:38:52.469: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:508: [0424/143852:INFO:ssl_client_socket_openssl.cc(508)] ~SSLClientSocketOpenSSL()
04-24 14:38:52.469: I/GATE(15434): <GATE-M>DEV_ACTION_ERROR</GATE-M>
04-24 14:38:52.477: V/webkit(15434): reportError errorCode(-11) desc(Couldn't establish a secure connection.)
04-24 14:38:52.532: I/GATE(15434): <GATE-M>DEV_ACTION_COMPLETED</GATE-M>
深入研究看起来我们可能需要重写 SSLProtocolFactory;但这似乎是针对自签名证书等的。我们正在连接到一个众所周知的第 3 方,他们的证书似乎没有任何问题。与往常一样,我们可能觉得 Android 的早期版本缺少某些东西;或解决已在较新版本中修复但不确定下一步该看哪里的问题。
这似乎是 Android v4.3 和更早版本中的错误,现在 Google 不在维护中,不会修补。我们正在连接的网站是 运行 TLS,但最近关闭了 SSLv3。它是一家支付提供商,PCI 合规性迫使提供商在来年禁用 SSLv3 和早期版本的 TLS 以保持合规性。我们还发现,虽然 Android 版本的 Chrome 能够与站点正确通信,但本机 Android 浏览器不能(因此复制了我们在 WebViewClient 中看到的内容)。令人沮丧的是,这意味着似乎没有针对此问题的安全解决方案。可能可以覆盖 SSLProviderFactory,但这看起来像是敲破坚果的大锤,会引发其他潜在的安全问题。
更新:最后这个问题也被我们连接的第 3 方解决了。在 Android 方面我们无能为力,但我认为这是对服务器上的某些内容进行排序的 bios 更新,这意味着它开始以 Android 可以处理的方式进行通信(我们不能从第 3 方那里得到更多关于他们做了什么的细节)。
我们的应用程序有选项卡,其中一个片段可以包含一个 webviewclient。用户现在报告 webviewclient 无法加载页面的问题。我们已确认服务器已启动并且 运行,我们还确定该问题发生在 v4.3 和所有早期版本中。我们还确认它在 v5.0 中工作正常;现在我们无法测试它是否在 4.4 中工作(我想这些信息只有在有人知道 4.4 和更新版本中发生的更改会导致所有早期版本中出现故障时才有用)。
所以实际的问题是我们创建了 webviewclient 并将其加载到片段中,网页(通过 HTTPS 连接)在所有版本的这种情况下每次都能完美加载。对于 v5.0,我们可以单击不同的选项卡并返回到带有 webviewclient 的选项卡;我们可以看到正在创建的片段并且一切都按预期工作,网页按预期加载。但对于 v4.3 及更早版本,我们看到正在创建片段,但 webviewclient 触发 onReceivedError 并显示 -11 错误代码(无法建立安全连接)。进一步查看调试日志,我们得到一个握手错误,这是调用的日志。有趣的是,我们连接的网站可以接受 TLS1.2;我们可以看到,当我们使用 Firefox 进入 URL 并使用开发工具等时,这个错误也很有趣。
04-24 14:38:52.415: W/chromium(15434): external/chromium/net/http/http_stream_factory_impl_job.cc:865: [0424/143852:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant:
04-24 14:38:52.446: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:310: [0424/143852:INFO:ssl_client_socket_openssl.cc(310)] ssl_ctx_ is used
04-24 14:38:52.469: E/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:899: [0424/143852:ERROR:ssl_client_socket_openssl.cc(899)] handshake failed; returned 0, SSL error code 5, net_error -107
04-24 14:38:52.469: V/chromium(15434): external/chromium/net/socket/ssl_client_socket_openssl.cc:508: [0424/143852:INFO:ssl_client_socket_openssl.cc(508)] ~SSLClientSocketOpenSSL()
04-24 14:38:52.469: I/GATE(15434): <GATE-M>DEV_ACTION_ERROR</GATE-M>
04-24 14:38:52.477: V/webkit(15434): reportError errorCode(-11) desc(Couldn't establish a secure connection.)
04-24 14:38:52.532: I/GATE(15434): <GATE-M>DEV_ACTION_COMPLETED</GATE-M>
深入研究看起来我们可能需要重写 SSLProtocolFactory;但这似乎是针对自签名证书等的。我们正在连接到一个众所周知的第 3 方,他们的证书似乎没有任何问题。与往常一样,我们可能觉得 Android 的早期版本缺少某些东西;或解决已在较新版本中修复但不确定下一步该看哪里的问题。
这似乎是 Android v4.3 和更早版本中的错误,现在 Google 不在维护中,不会修补。我们正在连接的网站是 运行 TLS,但最近关闭了 SSLv3。它是一家支付提供商,PCI 合规性迫使提供商在来年禁用 SSLv3 和早期版本的 TLS 以保持合规性。我们还发现,虽然 Android 版本的 Chrome 能够与站点正确通信,但本机 Android 浏览器不能(因此复制了我们在 WebViewClient 中看到的内容)。令人沮丧的是,这意味着似乎没有针对此问题的安全解决方案。可能可以覆盖 SSLProviderFactory,但这看起来像是敲破坚果的大锤,会引发其他潜在的安全问题。
更新:最后这个问题也被我们连接的第 3 方解决了。在 Android 方面我们无能为力,但我认为这是对服务器上的某些内容进行排序的 bios 更新,这意味着它开始以 Android 可以处理的方式进行通信(我们不能从第 3 方那里得到更多关于他们做了什么的细节)。