Date
Sep. 8th, 2024
 
2024年 8月 6日

Post: iOS 9 : ATS (App Transport Security)

iOS 9 : ATS (App Transport Security)

Published 12:09 Sep 18, 2015.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

相信很多小伙伴即将开始着手 iOS 9 的适配工作了,下面我们就来了解一下 iOS 9 的一项新特性: ATS

什么是 ATS

ATS 的全称是 App Transport Security,是iOS9的一个新特性,它的主要作用在于增强数据访问安全性。 App Transport Security Technote

在基于 iOS 9 的 SDK 编译的 APP 中,默认情况下任何使用 NSURLConnectionCFURL 以及 NSURLSessionHTTP请求,都会统一使用 TLS 1.2 协议。

什么是 SSL/TLS

SSL (Secure Sockets Layer ,安全套接层),及其继任者 TLS (Transport Layer Security ,传输层安全) 是为网络通信提供安全及数据完整性的一种安全协议。TLSSSL 在传输层对网络连接进行加密。

什么是 HTTP/HTTPS

HTTP 的全称为 HyperText Transfer Protocol,而 HTTPS 的全称为 Hyper Text Transfer Protocol over Secure Socket Layer,也即 HTTP over SSL。那么也就是说,HTTP 采用 SSL/TLS 协议就是从 HTTP 提升到 HTTPS 的过程,也就是 ATS

为什么要使用 ATS

从前面的介绍不难看出,不使用 SSL/TLSHTTP 通信是不加密的,这带来的风险是显而易见的,任何第三方都可以对你的通信进行窃听(eavesdropping)、篡改(tampering) 甚至冒充(pretending)。 SSL\TLS 的存在,恰恰是为了解决这三种风险,它对所有信息进行加密,且具备可靠有效的校验机制及身份证书。

我是否受到影响、我可以不使用 ATS 吗

如果你的网络请求使用的是第三方库 AFNetworking,由于其 AFHTTPRequestOperationManager 中的实现采用了我们前面提到的 NSURLConnection,因此在 AFNetworking 更新之前,如果你的 APP 是基于 iOS 9 的 SDK 编译,你和服务器的小伙伴可能要面临加班了。

苹果在其官方文档中指出 NSURLConnection 在 iOS 9 中已被废弃并建议使用 NSURLSession:

The NSURLConnection API in the Foundation framework. Use NSURLSession APIs instead.

因此,我们刚才提到的第三方类库 AFNetworking 对此也有一个更新计划: AFNetworking 更新计划

你可以在项目的 Target 中进入 Build Setting 找到 Architectures 下的 Base SDK 对所使用的 SDK 进行确认。

当然,虽然苹果并不建议,某些情况下你仍旧还是可以选择不启用 ATS (例如你使用了是你不具备控制权限且不支持 HTTPSCDN),在官方文档WWDC Session (@00:30:18) 也给出了解决方案:

If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn't follow this requirement, an error is thrown. If your app needs to make a request to an insecure domain, you have to specify this domain in your app's Info.plist file.

也就是说:

如果你希望完全禁用 ATS,具体的方法是通过将 Info.plist 中的 NSAppTransportSecurity 中的 NSAllowsArbitraryLoads 改为 YES

如果你只希望部分 URL 不使用 ATS,那么你需要在 Info.plist 中配置 NSExceptionDomains 来针对性的关闭 ATS 或是 ATS 的部分选项。在该字典中你可以使用的有:

  • NSIncludesSubdomains

  • NSExceptionAllowInsecureHTTPLoads

  • NS_ThirdParty_ExceptionAllowsInsecureHTTPLoads

  • NSExceptionRequiresForwardSecrecy

  • NS_ThirdParty_ExceptionRequiresForwardSecrecy

  • NSExceptionMinimumTLSVersion

  • NS_ThirdParty_ExceptionMinimumTLSVersion

其中带有 ThirdParty 关键字的条目与其去掉 ThirdParty 关键字后的同名条目功能相同。

其他第三方库例如 ASIHTTPRequest(已停止更新)、CFSocket 并没有受到影响。

另外,要注意,即使服务器已支持 SSL/TLS 1.2,但 ATS 要求站点使用支持 Forward Secrecy 协议的密码以及符合 ATS 规格 的证书。

官方文档 App Transport Security Technote CA 颁发的证书要求:

Certificates must be signed using a SHA256 or better signature hash algorithm, with either a 2048 bit or greater RSA key or a 256 bit or greater Elliptic-Curve (ECC) key. Invalid certificates result in a hard failure and no connection

如何使用 ATS

类型说明
HTTPS Only只有 HTTPS,在所有情况下一律使用 ATS
Mix & Match混合模式,仅针对部分通信禁用 ATS
Opt Out禁用 ATS,在任何情况下都不使用 ATS
Opt Out With Exceptions禁用 ATS 但允许例外,仅针对部分通信启用 ATS

下面分别做一下介绍:

HTTPS Only

如果你的 APP 没有 HTTPS 以外的通信,那么不需要做任何改变,也不需要禁用 ATS

如果你连接的服务器已经支持 SSL\TLS 1.2 仍旧无法在 iOS 9 中进行网络通信,你可能需要参照本文前面提到的 Forward Secrecy 部分。(点击跳转)

Mix & Match

毫无疑问,你的应用与一个不符合 ATS 要求的服务器通信是很有可能的:

  • 服务器不支持 HTTPS
  • 服务器支持 HTTPS 但没有使用 SSL\TLS 1.2
  • 服务器没有使用支持 Forward Secrecy 协议的密码

对于它们,我们需要在 Info.plist 中进行配置:

  • 服务器不支持 HTTPS
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
      <key>yourdomain.com</key>
      <dict>
          <key>NSExceptionAllowsInsecureHTTPLoads</key>
          <false/>
      </dict>
  </dict>
</dict>

这里我们通过定义例外情况(Exception),允许了在与该子域交互的时(仅针对该子域)暂时关闭 ATS。需要注意的是 NSExceptionAllowsInsecureHTTPLoads 关键字并不仅仅只是与使用 HTTPS 相关。

  • 服务器支持 HTTPS 但没有使用 SSL\TLS 1.2
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>yourdomain.com</key>
        <dict>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
        </dict>
    </dict>
</dict>

这里我们同样定义了例外情况(Exception),指明应该使用的最低 TLS 的版本。

  • 服务器没有使用支持 Forward Secrecy 协议的密码
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
      <key>yourdomain.com</key>
      <dict>
          <!--适用于这个特定域名下的所有子域-->
          <key>NSIncludesSubdomains</key>
          <true/>
          <!--扩展可接受的密码列表:这个域名可以使用不支持 Forward Secrecy 协议的密码-->
          <key>NSExceptionRequiresForwardSecrecy</key>
          <false/>
          <!--允许App进行不安全的HTTP请求-->
          <key>NSExceptionAllowsInsecureHTTPLoads</key>
          <true/>
          <!--在这里声明所支持的 TLS 最低版本-->
          <key>NSExceptionMinimumTLSVersion</key>
          <string>TLSv1.1</string>
      </dict>
  </dict>
</dict>

其中:

通过将 NSIncludesSubdomains 设置为 YES 来指明例外情况(Exception)适用于特定域名的所有子域。

通过将 NSExceptionRequiresForwardSecrecy 设置为 NO

扩展可接受的密码列表,来指明特定域名可以使用不支持 Forward Secrecy 协议的密码。

Opt Out

如果你需要完全禁用 ATS,或者你想偷懒,那么就像我们前面介绍的那样,你可以通过修改 Info.plist 文件来达到目的:

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

Opt Out With Exceptions

最后一种情况是,你希望单独针对某些例外情况(Exception)开启 ATS,我们同样通过修改 Info.plist 文件来达到目的:

<key>NSAppTransportSecurity</key>
        <dict>
            <key>NSAllowsArbitraryLoads</key>
            <true/>
            <key>NSExceptionDomains</key>
            <dict>
                <key>api.tutsplus.com</key>
                <dict>
                    <key>NSExceptionAllowsInsecureHTTPLoads</key>
                    <false/>
                </dict>
            </dict>
        </dict>

关于 Certificate Transparency

ATS 的大部分安全特性都是默认可用的,但如果你的证书支持 Certificate Transparency,你仍旧需要设置 NSRequiresCertificateTransparency 为可用。反之如果你的证书不支持 Certificate Transparency,请设置为不可用。

关于调试与错误信息输出

如果你需要调试一些因 ATS 产生的问题,你可能需要将 CFNETWORK_DIAGNOSTICS 设置为 1,以便输出包含被访问 URL 以及 ATS 错误的 NSURLSession 错误信息。

Pinned Message
HOTODOGO
The Founder and CEO of Infeca Technology.
Developer, Designer, Blogger.
Big fan of Apple, Love of colour.
Feel free to contact me.
反曲点科技创始人和首席执行官。
程序猿、设计师、奇怪的博主。
苹果死忠、热爱色彩斑斓的世界。
如有意向请随时 与我联系