跳过内容

iOS 网络通信

概述

几乎每个 iOS 应用程序都充当一个或多个远程服务的客户端。由于此网络通信通常发生在公共 Wi-Fi 等不受信任的网络上,因此传统的基于网络的攻击就成了潜在的问题。

大多数现代移动应用程序都使用基于 HTTP 的 Web 服务的变体,因为这些协议都有详细的文档和支持。

iOS App Transport Security (ATS)

从 iOS 9 开始,Apple 引入了 App Transport Security (ATS),它是由操作系统强制执行的一组安全检查,用于使用 URL Loading System(通常通过 URLSession)建立的连接,以始终使用 HTTPS。应用程序应遵循 Apple 的最佳实践,以正确保护其连接。

观看 Apple WWDC 2015 的 ATS 介绍视频.

ATS 执行默认服务器信任评估,并要求满足最低的安全要求。

默认服务器信任评估

当应用程序连接到远程服务器时,服务器使用 X.509 数字证书提供其身份。ATS 默认服务器信任评估包括验证证书

  • 未过期。
  • 具有与服务器 DNS 名称匹配的名称。
  • 具有有效的数字签名(未被篡改),并且可以追溯到 操作系统信任存储中包含的受信任的证书颁发机构 (CA),或者由用户或系统管理员安装在客户端上。

连接的最低安全要求

ATS 将阻止进一步未能满足一组 最低安全要求 的连接,包括

  • TLS 版本 1.2 或更高版本。
  • 使用 AES-128 或 AES-256 进行数据加密。
  • 证书必须使用 RSA 密钥(2048 位或更大)或 ECC 密钥(256 位或更大)进行签名。
  • 证书的指纹必须使用 SHA-256 或更高版本。
  • 该链接必须通过椭圆曲线 Diffie-Hellman Ephemeral (ECDHE) 密钥交换支持完全正向保密 (PFS)。

证书有效性检查

根据 Apple 的说法,“TLS 证书的信任状态的评估是按照既定的行业标准执行的,如 RFC 5280 中所述,并结合了新兴标准,如 RFC 6962(证书透明度)。在 iOS 11 或更高版本中,Apple 设备会定期更新已吊销和受限证书的当前列表。该列表是从证书吊销列表 (CRL) 聚合而来的,这些列表由 Apple 信任的每个内置根证书颁发机构及其从属 CA 颁发者发布。该列表还可能包括 Apple 自行决定的其他约束。每当使用网络 API 函数建立安全连接时,都会参考此信息。如果来自 CA 的吊销证书过多,无法单独列出,则信任评估可能需要联机证书状态响应 (OCSP),如果该响应不可用,则信任评估将失败。”

什么时候 ATS 不适用?

  • 使用较低级别的 API 时: ATS 仅适用于 URL Loading System,包括 URLSession 和在其之上的分层 API。它不适用于使用较低级别 API(如 BSD Sockets)的应用程序,包括那些在这些较低级别 API 之上实现 TLS 的应用程序(请参阅存档 Apple Developer 文档中的 “在 Apple 框架中使用 ATS”部分)。

  • 连接到 IP 地址、不完整的域名或本地主机时: ATS 仅适用于与公共主机名建立的连接(请参阅存档 Apple Developer 文档中的 “ATS 对远程和本地连接的可用性”部分)。系统不为与以下对象建立的连接提供 ATS 保护:

    • 互联网协议 (IP) 地址
    • 不完整的主机名
    • 使用 .local 顶级域 (TLD) 的本地主机
  • 包含 ATS 异常时: 如果应用程序使用 ATS 兼容的 API,它仍然可以使用 ATS 异常为特定场景禁用 ATS。

了解更多

ATS 异常

可以通过在 Info.plist 文件中的 NSAppTransportSecurity 键下配置异常来禁用 ATS 限制。这些例外可以应用于

  • 允许不安全连接 (HTTP),
  • 降低最低 TLS 版本,
  • 禁用完全正向保密 (PFS) 或
  • 允许连接到本地域名。

ATS 异常可以全局应用或按域名应用。应用程序可以全局禁用 ATS,但选择加入单个域名。来自 Apple Developer 文档的以下列表显示了 NSAppTransportSecurity 字典的结构。

NSAppTransportSecurity : Dictionary {
    NSAllowsArbitraryLoads : Boolean
    NSAllowsArbitraryLoadsForMedia : Boolean
    NSAllowsArbitraryLoadsInWebContent : Boolean
    NSAllowsLocalNetworking : Boolean
    NSExceptionDomains : Dictionary {
        <domain-name-string> : Dictionary {
            NSIncludesSubdomains : Boolean
            NSExceptionAllowsInsecureHTTPLoads : Boolean
            NSExceptionMinimumTLSVersion : String
            NSExceptionRequiresForwardSecrecy : Boolean   // Default value is YES
            NSRequiresCertificateTransparency : Boolean
        }
    }
}

来源:Apple Developer Documentation

下表总结了全局 ATS 异常。有关这些异常的更多信息,请参阅 官方 Apple Developer 文档中的表 2

描述
NSAllowsArbitraryLoads 全局禁用 ATS 限制,但 NSExceptionDomains 下指定的单个域名除外
NSAllowsArbitraryLoadsInWebContent 禁用从 Web 视图建立的所有连接的 ATS 限制
NSAllowsLocalNetworking 允许连接到不完整的域名和 .local 域名
NSAllowsArbitraryLoadsForMedia 禁用通过 AV Foundations 框架加载的媒体的所有 ATS 限制

下表总结了按域名 ATS 异常。有关这些异常的更多信息,请参阅 官方 Apple Developer 文档中的表 3

描述
NSIncludesSubdomains 指示 ATS 异常是否应应用于命名域的子域
NSExceptionAllowsInsecureHTTPLoads 允许与命名域建立 HTTP 连接,但不影响 TLS 要求
NSExceptionMinimumTLSVersion 允许与 TLS 版本低于 1.2 的服务器建立连接
NSExceptionRequiresForwardSecrecy 禁用完全正向保密 (PFS)

证明异常的合理性

从 2017 年 1 月 1 日开始,如果定义了以下 ATS 异常之一,Apple App Store 审核 需要提供理由

  • NSAllowsArbitraryLoads
  • NSAllowsArbitraryLoadsForMedia
  • NSAllowsArbitraryLoadsInWebContent
  • NSExceptionAllowsInsecureHTTPLoads
  • NSExceptionMinimumTLSVersion

必须仔细审查此内容,以确定它是否确实是应用程序预期用途的一部分。Apple 警告说,异常会降低应用程序的安全性,并建议在遇到 ATS 故障时仅在需要时配置异常,并首选服务器修复

示例

在以下示例中,ATS 是全局启用的(没有定义全局 NSAllowsArbitraryLoads),但 example.com 域(及其子域)显式设置了异常。考虑到该域由应用程序开发人员拥有,并且有充分的理由,此异常是可以接受的,因为它为所有其他域保留了 ATS 的所有好处。但是,始终最好如上所述修复服务器。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    </dict>
</dict>

有关 ATS 异常的更多信息,请参阅 Apple Developer Documentation 中 “防止不安全网络连接” 一文中的 “仅在需要时配置异常;首选服务器修复” 部分以及 有关 ATS 的博客文章

服务器信任评估

ATS 施加了扩展的安全检查,以补充传输层安全 (TLS) 协议规定的默认服务器信任评估。放宽 ATS 限制会降低应用程序的安全性。应用程序应首选在添加 ATS 异常之前改进服务器安全性的其他方法。

Apple Developer 文档解释说,应用程序可以使用 URLSession 自动处理服务器信任评估。但是,应用程序也可以自定义该过程,例如,它们可以

  • 绕过或自定义证书到期。
  • 放宽/扩展信任:接受会被系统拒绝的服务器凭据,例如,使用嵌入在应用程序中的自签名证书与开发服务器建立安全连接。
  • 加强信任:拒绝会被系统接受的凭据。
  • 等等

参考资料

iOS 网络 API

自 iOS 12.0 起,Network 框架和 URLSession 类提供异步和同步加载网络和 URL 请求的方法。较旧的 iOS 版本可以使用 Sockets API

网络框架 (Network Framework)

Network 框架在 2018 年的 Apple 全球开发者大会 (WWDC) 上推出,是 Sockets API 的替代品。这个低级网络框架提供了用于发送和接收数据的类,内置了动态网络、安全和性能支持。

如果使用参数 using: .tls,则默认情况下在 Network 框架中启用 TLS 1.3。它是优于传统 安全传输 框架的首选选项。

URLSession

URLSession 构建于 Network 框架之上,并使用相同的传输服务。如果端点是 HTTPS,该类也默认使用 TLS 1.3。

URLSession 应该用于 HTTP 和 HTTPS 连接,而不是直接使用 Network 框架。 URLSession 类原生支持这两种 URL 方案,并针对此类连接进行了优化。它需要更少的样板代码,从而减少了出错的可能性,并默认确保安全连接。仅当存在低级和/或高级网络要求时,才应使用 Network 框架。

官方 Apple 文档包括使用 Network 框架 实现 netcat 和使用 URLSession 将网站数据提取到内存 的示例。