Xamarin.iOS 中的应用传输安全性

应用传输安全性 (ATS) 会强制实现 Internet 资源(例如应用的后端服务器)与应用之间的安全连接。

本文将介绍应用传输安全性对 iOS 9 应用实现的安全更改,以及这对 Xamarin.iOS 项目意味着什么,其中将介绍 ATS 配置选项,以及如何选择退出 ATS(如果需要)。 由于 ATS 默认已启用,任何不安全的 Internet 连接都会在 iOS 9 应用中引发异常(除非明确允许)。

关于应用传输安全性

如上所述,ATS 可确保 iOS 9 和 OS X EI Capitan 中的所有 Internet 通信都符合安全连接最佳做法,从而防止直接通过应用或其正在使用的库意外泄露敏感信息。

对于现有应用,请尽可能实现 HTTPS 协议。 对于新的 Xamarin.iOS 应用,应仅在与 Internet 资源通信时使用 HTTPS。 此外,高级 API 通信必须使用具备前向保密性的 TLS 版本 1.2 进行加密。

NSUrlConnectionCFUrlNSUrlSession 建立的任何连接, 都默认在为 iOS 9 和 OS X 10.11 (El Capitan) 生成的应用中使用 ATS。

默认 ATS 行为

由于为 iOS 9 和 OS X 10.11 (El Capitan) 生成的应用中默认启用了 ATS,因此使用 NSUrlConnectionCFUrlNSUrlSession 的所有连接都受 ATS 安全要求的约束。 如果连接不符合这些要求,它们将失败并出现异常。

ATS 连接要求

ATS 将对所有 Internet 连接强制实施以下要求:

  • 所有连接密码都必须使用前向保密。 请参阅下方接受的密码列表。
  • 传输层安全性 (TLS) 协议必须为版本 1.2 或更高版本。
  • 所有证书都必须至少具有 2048 位或更高 RSA 密钥,或 256 位或更大的椭圆曲线 (ECC) 密钥,以及至少一个 SHA256 指纹。

同样,由于在 iOS 9 中默认启用 ATS,因此尝试建立不符合这些要求的连接将导致引发异常。

ATS 兼容的密码

ATS 安全 Internet 通信接受以下前向保密密码类型:

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

有关使用 iOS Internet 通信类的详细信息,请参阅 Apple 的 NSURLConnection 类参考NSURLSession 类参考

支持 Xamarin.iOS 中的 ATS

由于 iOS 9 和 OS X El Capitan 默认启用了 ATS,因此如果 Xamarin.iOS 应用程序或其使用的任何库或服务与互联网连接,就需要采取一些措施,否则连接将导致引发异常。

对于现有应用,Apple 建议尽快支持 HTTPS 协议。 如果因为连接到不支持 HTTPS 的第三方 Web 服务无法提供支持,或者支持 HTTPS 是不切实际的,则可以选择退出 ATS。 有关详细信息,请参阅下方的“选择退出 ATS”部分。

对于新的 Xamarin.iOS 应用,应仅在与 Internet 资源通信时使用 HTTPS。 同样,在某些情况下(例如使用第三方 Web 服务),这是不可能的,你需要选择退出 ATS。

此外,ATS 会强制高级 API 通信使用具备前向保密性的 TLS 版本 1.2 进行加密。 有关更多详细信息,请参阅上方的 ATS 连接要求ATS 兼容密码部分。

虽然你可能不熟悉 TLS(传输层安全性),但它是 SSL(安全套接字层)的继任者,并会提供加密协议集合,用于通过网络连接强制执行安全性。

TLS 级别由正在使用的 Web 服务控制,因此不受应用控制。 HttpClientModernHttpClient 应自动使用服务器支持的最高级别的 TLS 加密。

根据要与之通信的服务器(特别是如果是第三方服务),可能需要禁用前向保密或选择较低的 TLS 级别。 有关详细信息,请参阅下方的“配置 ATS 选项”部分。

重要

应用传输安全性不适用于使用“托管 HTTPClient 实现”的 Xamarin 应用。 它仅适用于使用 CFNetwork HTTPClient 实现NSURLSession HTTPClient 实现 的连接。

设置 HTTPClient 实现

若要设置 iOS 应用使用的 HTTPClient 实现,请双击“解决方案资源管理器”中的“项目”以打开“项目选项”。 导航到“iOS 生成”,然后在“HttpClient 实现”下拉列表中选择所需的客户端类型:

设置 iOS 生成选项

托管处理程序

托管处理程序是随早期版本的 Xamarin.iOS 一起提供的完全托管的 HttpClient 处理程序,是默认处理程序。

优点:

  • 它是与 Microsoft .NET 和旧版 Xamarin 最兼容的。

缺点:

  • 它未与 iOS 完全集成(例如,它仅限于 TLS 1.0)。
  • 它通常比本机 API 慢得多。
  • 它需要更多的托管代码并创建更大的应用。

CFNetwork 处理程序

基于 CFNetwork 的处理程序是基于本机 CFNetwork 框架的。

优点:

  • 使用本机 API 提高性能并使用较小的可执行大小。
  • 添加了对较新的标准(如 TLS 1.2)的支持。

缺点:

  • 需要 iOS 6 或更高版本。
  • 不支持 watchOS。
  • 某些 HttpClient 功能和选项不可用。

NSUrlSession 处理程序

基于 NSUrlSession 的处理程序是基于本机 NSUrlSession API 的。

优点:

  • 使用本机 API 提高性能并使用较小的可执行大小。
  • 添加了对较新的标准(如 TLS 1.2)的支持。

缺点:

  • 需要 iOS 7 或更高版本。
  • 某些 HttpClient 功能和选项不可用。

诊断 ATS 问题

尝试直接或从 iOS 9 中的 Web 视图连接到 Internet 时,可能会收到以下格式的错误:

应用传输安全已阻止明文 HTTP (http://www.-the-blocked-domain.com) 资源负载,因为它不安全。 可以通过应用的 Info.plist 文件配置临时异常。

在 iOS9 中,应用传输安全性 (ATS) 会强制实现 Internet 资源(例如应用的后端服务器)与应用之间的安全连接。 此外,ATS 要求使用 HTTPS 协议和高级 API 通信进行通信,以便使用前向保密的 TLS 版本 1.2 进行加密。

由于为 iOS 9 和 OS X 10.11 (El Capitan) 生成的应用中默认启用了 ATS,因此使用 NSURLConnectionCFURLNSURLSession 的所有连接都受 ATS 安全要求的约束。 如果连接不符合这些要求,它们将失败并出现异常。

Apple 还提供 TLSTool 示例应用,这些应用可以编译(或选择性地转码为 Xamarin 和 C#),并用于诊断 ATS/TLS 问题。 有关如何解决此问题的信息,请参阅下方的“选择退出 ATS”部分。

配置 ATS 选项

可以通过在应用的 Info.plist 文件中为特定键设置值来配置 ATS 的多个功能。 以下键可用于控制 ATS(缩进以显示它们如何嵌套):

NSAppTransportSecurity
    NSAllowsArbitraryLoads
    NSAllowsArbitraryLoadsInWebContent
    NSExceptionDomains
    <domain-name-for-exception-as-string>
        NSExceptionMinimumTLSVersion
        NSExceptionRequiresForwardSecrecy
        NSExceptionAllowsInsecureHTTPLoads
        NSRequiresCertificateTransparency
        NSIncludesSubdomains
        NSThirdPartyExceptionMinimumTLSVersion
        NSThirdPartyExceptionRequiresForwardSecrecy
        NSThirdPartyExceptionAllowsInsecureHTTPLoads

每个键具有以下类型和含义:

  • NSAppTransportSecurity (Dictionary) - 包含 ATS 的所有设置键和值。
  • NSAllowsArbitraryLoads (Boolean) - 如果 YES ATS 将禁用任何NSExceptionDomains 中列出的域。 对于列出的域,将使用指定的安全设置。
  • NSAllowsArbitraryLoadsInWebContent (Boolean) - 如果 YES 允许网页正确加载,而应用的其余部分仍启用 Apple 传输安全性 (ATS) 保护。
  • NSExceptionDomains (Dictionary) - ATS 应用于给定域的安全设置的域集合。
  • <domain-name-for-exception-as-string> (Dictionary) - 给定域的异常集合(例如 www.xamarin.com)。
  • NSExceptionMinimumTLSVersion (String) - 最低 TLS 版本为 TLSv1.0TLSv1.1TLSv1.2(其为默认值)。
  • NSExceptionRequiresForwardSecrecy (Boolean) - 如果 NO 域不必使用具有前向安全性的密码。 默认值为 YES
  • NSExceptionAllowsInsecureHTTPLoads (Boolean) -如果 NO(默认值),则与此域的所有通信都必须位于 HTTPS 协议中。
  • NSRequiresCertificateTransparency (Boolean) - 如果 YES,域的安全套接字层 (SSL) 必须包含有效的透明度数据。 默认值为 NO
  • NSIncludesSubdomains (Boolean) - 如果 YES,这些设置将覆盖此域的所有子域。 默认值为 NO
  • NSThirdPartyExceptionMinimumTLSVersion (String) - 当域名是开发者无法控制的第三方服务时使用的 TLS 版本。
  • NSThirdPartyExceptionRequiresForwardSecrecy (Boolean) - 如果 YES,第三方域需要前向保密。
  • NSThirdPartyExceptionAllowsInsecureHTTPLoads (Boolean) - 如果 YES,ATS 将允许与第三方域进行非安全通信。

选择退出 ATS

虽然 Apple 强烈建议使用 HTTPS 协议和安全通信访问基于互联网的信息,但可能并非总是可行。 例如,如果正在与第三方 Web 服务通信,或在应用中使用 Internet 交付的广告。

如果 Xamarin.iOS 应用必须向不安全的域发出请求,则对应用的 Info.plist 文件的以下更改将禁用 ATS 对给定域强制实施的安全默认值:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>www.the-domain-name.com</key>
        <dict>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

在 Visual Studio for Mac 中,双击解决方案资源管理器中的 Info.plist 文件,切换到视图并添加上述键:

添加指定键后 Info.plist 文件的源视图。

如果你的应用需要从非安全网站加载和显示 Web 内容,请将以下内容添加到应用的 Info.plist 文件,以允许网页正确加载,同时仍为应用的其余部分启用 Apple 传输安全性 (ATS) 保护:

<key>NSAppTransportSecurity</key>
<dict>
    <key> NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

(可选)你可以对应用的 Info.plist 文件进行以下更改,以对所有域和 Internet 通信完全禁用 ATS:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

在 Visual Studio for Mac 中,双击解决方案资源管理器中的 Info.plist 文件,切换到视图并添加上述键:

指定 NSAllowsArbitraryLoadsInWebContent 和 NSAllowsArbitraryLoads 后 Info.plist 文件的源视图。

重要

如果你的应用程序需要连接到不安全的网站,则应始终使用 NSExceptionDomains 输入域作为例外,而不是使用 NSAllowsArbitraryLoads 完全关闭 ATS。 NSAllowsArbitraryLoads 仅应在极端的紧急情况下使用。

请再次注意,如果切换到安全连接不可用或不切实际,禁用 ATS 应作为最后手段。

总结

本文介绍了应用传输安全性(ATS),并介绍了它强制执行与 Internet 的安全通信的方式。 首先,我们介绍了 ATS 对 iOS 9 上运行的 Xamarin.iOS 应用所做的更改。 然后,我们介绍了控制 ATS 的功能和选项。 最后,我们介绍了如何在 Xamarin.iOS 应用中选择退出 ATS。