【问题标题】:Unexpected exception while opening secure websocket connection打开安全 websocket 连接时出现意外异常
【发布时间】:2017-02-22 15:50:22
【问题描述】:

我正在尝试打开从 Xamarin Android 应用程序到 IIS 服务器的安全 websocket 连接。除了 Samsung Tab E 之外,它在我用过的所有设备上都能正常运行。甚至其他三星设备也能正常工作。

我正在使用 Websockets.PCL 库和常规代码:

var _webSocket = WebSocketFactory.Create();
_webSocket.OnOpened += _webSocket_Opened;
_webSocket.OnError += _webSocket_Error;
_webSocket.Open("wss://server.name.here/path/also/");

在这种情况下,错误处理程序被调用:

[websockets] javax.net.ssl.SSLException
[websockets] javax.net.ssl.SSLException:委托任务中发生错误:javax.net.ssl.SSLException:意外异常

设备通过 Chrome 或其他应用程序的 SSL 连接没有问题,而不是与此服务器或其他服务器的连接。从这个应用程序通过 SignalR 连接到同一个 IIS 服务器也没有问题。

当另一个第三方库尝试从单独的网站检查许可证并记录错误时,确实会出现问题:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL 握手中止: ssl=0x803b3b28: SSL 库失败,通常是协议错误

我不知道它试图联系哪个地址,所以无法检查那里发生了什么。但这也适用于其他设备。

这让我相信 Tab E 中的 Android(v4.4.4,最新可用)的 SSL 实现有问题,因为通过 javax.net.ssl 进行的这两次连接尝试都失败了。但意外的异常并没有提供太多信息。

如何解决这个问题?我不介意使用 SignalR 使用的 websockets 实现(因为它可以工作),但据我所知,它并没有真正公开为可供使用的通用系统。

其他信息

服务器确实可以很好地与 TLS1 通信,并据我所知发送整个证书路径,所以这不应该是问题,除非根不知道(如果那样的话,我希望握手失败是这样)。用 openssl 测试显示:

证书链
0 s:/OU=域控制验证/OU=PositiveSSL/CN=our.domain.com
i:/C=GB/ST=大曼彻斯特/L=索尔福德/O=COMODO CA Limited/CN=COMODO RSA 域验证安全服务器 CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA 域验证安全服务器 CA
i:/C=GB/ST=大曼彻斯特/L=索尔福德/O=COMODO CA Limited/CN=COMODO RSA 证书颁发机构
2 s:/C=GB/ST=大曼彻斯特/L=索尔福德/O=COMODO CA Limited/CN=COMODO RSA 证书颁发机构
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root

未发送客户端证书 CA 名称
服务器临时密钥:ECDH,P-256,256 位

新,TLSv1/SSLv3,密码是 ECDHE-RSA-AES256-SHA
服务器公钥为 2048 位

不幸的是,openssl 不再支持 ´-ssl2` 标志。在线工具说禁用了 SSL2,启用了 SSL3、TLS1、TLS1.1 和 TLS1.2。

我可以尝试自定义 SSLSocketFactory 路由,但必须看看它如何通过 Xamarin 和 Websockets.PCL。

【问题讨论】:

  • 很可能不是旧 Android 版本的问题,因为在 4.2 设备上也可以正常工作
  • 我会假设几件事; CA 证书不同,您需要通过自己的 TrustManager 自己处理客户端证书,或者您使用的是自签名证书,因此自定义 TrustManager 可以解决它。 4.2 是与 4.4 不同的 ABI 版本,并且在 KitKat 与 JB 或 ICS 下的证书存在许多问题......此外,由于性能问题,该设备(Tab-E)是一个奇怪的 Samsung-KitKat 变体...... . 你的服务器是否只支持 TLS1.1? TLS1.2?...等...
  • 证书来自 Comodo,服务器提供了完整的路径。我必须确保服务器支持什么,它不应该仅限于当前的最佳实践,而且还支持更早的 SSL/TLS,但是当我连接到它时我会添加它。它也只是那个设备,其他 4.4s 和其他从 4.2 到 6.0 的工作正常,所以我认为三星搞砸了。几个小时后获得更多信息。
  • 您可以做的一些快速测试是:openssl s_client -connect google.com:80 -tls1 openssl s_client -connect google.com:80 -tls1(替换您的 FQDN)您可以更改 @987654325 @ 与-ssl3-ssl2-tls2 等...您还可以确认您的服务器正在发送 Comodo 中间证书等...

标签: android ssl xamarin websocket


【解决方案1】:

在 Android 中搜索 SSL 问题后,我找到了适合我的案例的解决方案。 Florian Krauthan 写过关于这些事情的文章,并谈到了 using the SSLSocketFactory on Android 4.1+ 以允许使用 TLS1.1 等。

这让我看到了另一篇文章,他解释了 Google Play Services can be used to inject a newer OpenSSL library 如何进入整个应用程序。这种方法也适用于我的问题。

唯一需要做的就是在主Activity的OnCreate()方法的开头添加如下代码:

Android.Gms.Security.ProviderInstaller.InstallIfNeeded(this);

在此之后,应用程序将使用 Google Play 服务的 OpenSSL 库,因此所有连接都可以正常工作,并且由于使用了更新的版本,内置 Android OpenSSL 库中可能存在的已知错误会得到缓解。

当然,对于尚未使用 Google Play 服务的任何人来说,这可能不是一个解决方案,因为它会极大地增加应用程序的大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多