打开安全websocket连接时出现意外异常

时间:2016-10-13 13:29:08

标签: android ssl xamarin websocket

我正在尝试打开从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 = Salford / O = COMODO CA Limited / CN = COMODO RSA域验证安全服务器CA
   1 s:/ C = GB / ST =大曼彻斯特/ L = Salford / O = COMODO CA Limited / CN = COMODO RSA域验证安全服务器CA
     i:/ C = GB / ST =大曼彻斯特/ L = Salford / O = COMODO CA Limited / CN = COMODO RSA认证机构
   2 s:/ C = GB / ST =大曼彻斯特/ L = Salford / O = COMODO CA Limited / CN = COMODO RSA认证机构
     i:/ C = SE / O = AddTrust AB / OU = AddTrust外部TTP网络/ CN = AddTrust外部CA根

     

没有发送客户端证书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。

1 个答案:

答案 0 :(得分: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如何进入整个应用程序。这个方法也适用于我的问题。

唯一需要做的是将以下代码添加到主要活动的OnCreate()方法的开头:

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

此后,该应用程序将使用Google Play服务' OpenSSL库使所有连接都能正常运行,并且内置的Android OpenSSL库中可能存在的已知错误因使用了较新的版本而得到缓解。

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