【发布时间】:2017-07-05 12:04:55
【问题描述】:
我正在开发一个 Xmarain.Forms 应用程序,该应用程序最初可以在 Android 上运行,以及它将连接到的服务。该服务是 WCF 服务,需要使用安全传输来发送消息,因此设置为使用 https。
我可以通过 SoapUI 和使用相同客户端代理库构建的控制台程序正确连接和使用该服务,但是当我尝试使用 Xamarin 应用程序时它失败了。在模拟器中运行时,异常为 TimeoutException,但在实际设备上安装时,异常为 WebException,消息为“错误:SecureChannelFailure(身份验证或解密失败”,内部异常堆栈为:
- 带有消息“身份验证或解密失败”的 IOException
- IOException 并带有消息“发送 TLS 警报时出错 (Fatal:InternalError)”
- IOException 带有消息“身份验证或解密失败。
- IOException 出现消息“无法从传输连接中读取数据:连接被对等方重置”
完整的堆栈跟踪作为附件包含在下面。完整代码可在https://github.com/staircase27/WcfXamarinHttpBugExample 获得,以及如何设置和使用它的说明。示例代码使用 http 和 https 进行连接,以显示差异并显示一个有效而另一个无效。我还在测试时检查了设备是否可以使用其网络浏览器访问服务,因此这不是防火墙或路由问题。
我还对连接进行了有线共享,以查看连接失败的确切位置以及在 TLS v1.0 级别失败。该应用程序(在我测试过的两台设备上)正在发送客户端问候,并且服务正在响应 TCP RST 数据包而不是服务器问候。我还使用成功的网络浏览器从测试设备执行了连接,主要区别在于支持的加密类型,特别是应用程序仅提供使用
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_CBC_SHA
- TLS_RSA_WITH_3DES_EDE_CBC_SHA
- TLS_RSA_WITH_RC4_128_SHA
- TLS_RSA_WITH_RC4_128_MD5
- TLS_RSA_WITH_DES_CBC_SHA
在哪里都使用了工作连接
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
具有两个连接的已过滤wireshark 位于https://github.com/staircase27/WcfXamarinHttpBugExample/raw/master/Mobile%20WCF%20https%20Capture%20-%20Filtered.pcapng。第一个连接来自应用程序,并以 tcp rst 失败。第二个是从安卓网络浏览器开始连接。
我已启用所有版本的 TLS 和所有密码套件,但它没有更改应用程序中的 wireshark 跟踪或异常。
我还按照@tomasr 的建议检查了 SChannel 事件日志,发现了以下事件:
- SSL 客户端握手成功完成。协商的密码参数如下。协议:TLS 1.0。密码套件:0xc014。交换强度:256
(在启用所有版本的 TLS 之前,事件是:
- 从远程客户端应用程序接收到 TLS 1.0 连接请求,但服务器不支持客户端应用程序支持的任何密码套件。 SSL 连接请求失败。
- 生成了以下致命警报:40。内部错误状态为 1205。
)
【问题讨论】:
-
您最好的选择可能是捕获网络跟踪。听起来 SSL 握手失败了。可能与 stackoverflow.com/questions/4926676/… 相同,这与在 Xamarin 端验证服务器证书失败有关。
-
你确定和这个stackoverflow.com/questions/38528616/…没有关系
-
查看wireshark跟踪,我不认为这是密码套件列表,因为我预计这会导致SSL警报而不是立即重置连接。我想知道客户端 Hello 上是否缺少服务器名称指示符 (SNI) 扩展(如果服务器上的所有 SSL 绑定都是基于 SNI 的,那么没有 SNI 将意味着服务器无法选择要呈现给客户端的证书)。然而,这也不完全有意义,因为工作跟踪有一个带有 IP 地址的 SNI,而不是主机名..
-
服务器是Windows/IIS吗?如果是这样,SCHANNEL 日志记录可能会有所帮助:support.microsoft.com/en-us/help/260729/…
-
这实际上是一个非常明确的错误信息!是的,xamarin 客户端提供的密码集只是......不是很好。您可以在服务器上使用诸如 nartac.com/Products/IISCrypto 之类的工具来检查服务器上启用了哪些密码,并且可以选择启用 xamarin 提供的密码之一。不是最好的选择,但不确定是否有更好的选择。
标签: c# android wcf xamarin xamarin.android