首页 > 解决方案 > 托管 Xamarin HttpClient 实现是否支持 TLS 1.2?

问题描述

应用程序传输层安全性(iOSAndroid)的官方 Xamarin 文档声明托管的HttpClient 实现仅支持 TLS 1.0。它强烈建议将 Xamarin 应用程序更新为本机 HttpClient 实现以支持 TLS 1.2。Visual Studio 也说明了这一点:

在此处输入图像描述

但是,文档是矛盾的。在描述托管HttpClient 实现时,它声明如下:

它没有与操作系统完全集成(例如,仅限于 TLS 1.0)。

后来的文档有相互矛盾的陈述,例如:

从 Xamarin.Android 8.3 开始,HttpClientHandler 默认为 Boring SSL ...它支持 TLS 1.2+。

此外,这篇非常有用的 Xamarin 博客文章指出,通过选择SSL/TLS 选项“本机 TLS 1.2”(这是 iOS 上的默认设置,在 iOS 上无法更改),托管 HttpClient 实现确实可以实现 TLS 1.2。

最后但同样重要的是,我针对仅支持 TLS 1.2的https://www.nist.gov测试了当前稳定的 Xamarin 版本1的 HttpClient。我验证了服务器只接受 TLS 1.2:

openssl s_client -connect nist.gov:443 -no_tls1_2

如果托管的 HttpClient 实现确实只支持 TLS 1.0,我预计以下连接会失败:

var client = new HttpClient();
var result = await client.GetStringAsync("https://www.nist.gov");

但是,通过以下设置连接成功:

这导致我提出以下问题:

  1. 当说明托管 HttpClient 实现仅支持 TLS 1.0 时,Xamarin 文档是否已过时?
  2. 我对https://www.nist.gov的测试有效吗?它是否确实表明托管的 HttpClient 实现支持 TLS 1.2?还是我错过了什么?

1 Visual Studio 7.5.2(内部版本 40)、Xamarin.iOS 11.12.0.4、Xamarin.Android 8.3.3.2

标签: xamarinxamarin.iosxamarin.androidtls1.2

解决方案


如果您使用“本机”处理程序(Android 或 iOS),则它使用本机 API 来实现HttpClientHandler功能,因此“依赖于平台”取决于是否支持 TLS1.2,即 Android 5/API-21 不支持原生支持 TLS1.2,大多数 Android 开发者使用 3rd-party lib...

当您启用“本机 SSL/TLS”时,它是使用 Google 的 BoringSSL(现在包含在您的应用程序包中)而不是本机平台 API。因此,即使使用“托管”HttpClientHandler 也支持 TLS1.2。此选项允许“.Net framework/Mono”支持 iOS 和 Android 上最新的 SSL/TLS,例如 .Net Sockets、WebClient 等。当然还有 HttpClient。

https://www.nist.gov测试:

Android Handler / Managed SSL    :  No exception
Managed Handler / Native SSL/TLS :  No exception
Android Handler / Native SSL/TLS :  No exception
Managed Handler / Managed SSL    :  Error: SecureChannelFailure 

安全通道故障

MonoDroid] UNHANDLED EXCEPTION:
[MonoDroid] System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: Error: SecureChannelFailure (The authentication or decryption has failed.) --->
System.IO.IOException: The authentication or decryption has failed. --->
System.IO.IOException: Error while sending TLS Alert (Fatal:InternalError): System.IO.IOException: The authentication or decryption has failed. --->
System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer. ---> 
System.Net.Sockets.SocketException: Connection reset by peer

推荐阅读