Android 的 HttpClient 堆栈和 SSL/TLS 实现选择器

HttpClient 堆栈和 SSL/TLS 实现选择器确定 Xamarin.Android 应用将使用的 HttpClient 和 SSL/TLS 实现。

项目必须引用 System.Net.Http 程序集。

警告

2018 年 4 月 – 由于安全要求的提高(包括 PCI 合规性),主要云服务提供商和 Web 服务器预计将停止支持低于 1.2 的 TLS 版本。 在早期版本的 Visual Studio 中创建的 Xamarin 项目默认使用旧版 TLS。

为了确保应用继续与这些服务器和服务配合使用,应使用如下所示的 Android HttpClientNative TLS 1.2 设置更新 Xamarin 项目,然后重新生成应用并将其重新部署到用户

在“项目选项”>“Android 选项”中,单击“高级选项”按钮可以访问 Xamarin.Android HttpClient 配置

下面是 TLS 1.2 支持的建议设置:

Visual Studio Android Options

替代配置选项

AndroidClientHandler

AndroidClientHandler 是新的处理程序,它委托给本机 Java/OS 代码,而不是在托管代码中实现所有内容。 这是建议的选项

优点

  • 使用本机 API 提高性能并使用较小的可执行大小。
  • 支持最新标准,例如 TLS 1.2。

缺点

  • 需要 Android 4.1 或更高版本。
  • 某些 HttpClient 功能/选项不可用。

托管 (HttpClientHandler)

托管处理程序是早期 Xamarin.Android 版本随附的完全托管型 HttpClient 处理程序。

优点

  • 它与 MS .NET 和旧 Xamarin 版本最兼容(功能)。

缺点

  • 它没有与操作系统完全集成(例如仅限于 TLS 1.0)。
  • 它通常比本机 API 慢得多(例如加密)。
  • 它需要更多的托管代码,可创建较大的应用程序。

选择处理程序

AndroidClientHandlerHttpClientHandler 之间的选择取决于应用程序的需求。 例如,对于以下情况,建议使用 AndroidClientHandler 来获得最新安全支持。

  • 需要 TLS 1.2+ 支持。
  • 应用面向 Android 4.1 (API 16) 或更高版本。
  • 需要 HttpClient 的 TLS 1.2+ 支持。
  • 不需要 WebClient 的 TLS 1.2+ 支持。

如果需要 TLS 1.2+ 支持但必须支持 Android 4.1 之前的 Android 版本,则 HttpClientHandler 是一个不错的选择。 如果需要 WebClient 的 TLS 1.2+ 支持,这也是一个不错的选择。

从 Xamarin.Android 8.3 开始,HttpClientHandler 默认使用 Boring SSL (btls) 作为基础 TLS 提供程序。 Boring SSL TLS 提供程序具有以下优势:

  • 它支持 TLS 1.2+。
  • 它支持所有 Android 版本。
  • 它为 HttpClientWebClient 提供 TLS 1.2+ 支持。

使用 Boring SSL 作为基础 TLS 提供程序的缺点是,它会增加生成的 APK 的大小(每个受支持的 ABI 会增加大约 1MB 的额外 APK 大小)。

从 Xamarin.Android 8.3 开始,默认 TLS 提供程序是 Boring SSL (btls)。 如果你不想使用 Boring SSL,可以通过将 $(AndroidTlsProvider) 属性设置为 legacy 来还原到历史托管 SSL 实现(有关设置生成属性的详细信息,请参阅生成过程)。

以编程方式使用 AndroidClientHandler

Xamarin.Android.Net.AndroidClientHandler 是专门针对 Xamarin.Android 的 HttpMessageHandler 实现。 此类的实例将对所有 HTTP 连接使用本机 java.net.URLConnection 实现。 理论上,这会提高 HTTP 性能并缩小 APK 大小。

此代码片段是一个演示如何显式获取 HttpClient 类的单个实例的示例:

// Android 4.1 or higher, Xamarin.Android 6.1 or higher
HttpClient client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler ());

注意

基础 Android 设备必须支持 TLS 1.2(即 Android 4.1 及更高版本)。 请注意,Android 5.0+ 才正式支持 TLS 1.2。 不过,某些设备在 Android 4.1+ 中支持 TLS 1.2。

SSL/TLS 实现生成选项

此项目选项控制所有 Web 请求(HttpClientWebRequest)将使用哪个基础 TLS 库。 默认会选择 TLS 1.2:

例如:

var client = new HttpClient();

如果 HttpClient 实现设置为“托管”,并且 TLS 实现设置为“本机 TLS 1.2+”,则 client 对象将自动为其 HTTP 请求使用托管 HttpClientHandler 和 TLS 1.2(由 BoringSSL 库提供)。

但是,如果 HttpClient 实现设置为 AndroidHttpClient,则所有 HttpClient 对象都将使用基础 Java 类 java.net.URLConnection,并且不受“TLS/SSL 实现”值的影响WebRequest 对象将使用 BoringSSL 库。

控制 SSL/TLS 配置的其他方式

Xamarin.Android 应用程序可以通过三种方式控制 TLS 设置:

  1. 在“项目选项”中选择 HttpClient 实现和默认的 TLS 库。
  2. 以编程方式使用 Xamarin.Android.Net.AndroidClientHandler
  3. 声明环境变量(可选)。

在这三个选项中,建议的方法是使用 Xamarin.Android 项目选项来声明整个应用的默认 HttpMessageHandler 和 TLS。 然后,根据需要以编程方式实例化 Xamarin.Android.Net.AndroidClientHandler 对象。 上面介绍了这些选项。

下面解释第三个选项 – 使用环境变量。

声明环境变量

有两个环境变量与 Xamarin.Android 中 TLS 的使用相关:

  • XA_HTTP_CLIENT_HANDLER_TYPE – 此环境变量声明应用程序将使用的默认 HttpMessageHandler。 例如:

    XA_HTTP_CLIENT_HANDLER_TYPE=Xamarin.Android.Net.AndroidClientHandler
    
  • XA_TLS_PROVIDER – 此环境变量声明要使用哪个 TLS 库,可以是 btlslegacydefault(与省略此变量相同):

    XA_TLS_PROVIDER=btls
    

此环境变量是通过向项目添加环境文件来设置的。 环境文件是 Unix 格式的纯文本文件,其中包含生成操作 AndroidEnvironment

有关环境变量和 Xamarin.Android 的详细信息,请参阅 Xamarin.Android 环境指南。