苹果文档翻译 iOS10 NSAppTransportSecurity
- 原文链接
- 原文版本:2016-09-07
- 翻译时间:2016-09-07
本文截取自苹果官方文档 Information Property List Key Reference ---> Cocoa Keys ---> NSAppTransportSecurity
NSAppTransportSecurity
(对应的值为字典类型)被用来定义 app 在进行网络请求时的安全设定:为现有安全机制设定特例,或者开启新的安全特性。
在苹果的开发平台上,有一种被称为App Transport Security(ATS)
的网络安全机制,适用于 app 以及 app extension,默认开启。这项机制确保 app 在进行网络访问时,使用业界标准的,没有已知重大安全隐患的协议和加密方式,以此确保用户的隐私和数据完整性。从而培养用户对您的 app 的信任。
通过在info.plist
中配置这个键,开发者可以自定义网络安全策略。例如:
- 允许针对个别服务器的不安全访问。
- 允许不安全的 web 或媒体内容访问,但不影响整个 app 的 ATS 策略。
- 启用新的安全特性,例如
Certificate Transparency
。
对NSAppTransportSecurity
的支持自 iOS9.0,OS X v10.11 开始,适用于 app 和 app extension。
自 iOS10.0,macOS 10.12 开始,增加了对下列子键的支持:
- NSAllowsArbitraryLoadsInMedia
- NSAllowsArbitraryLoadsInWebContent
- NSRequiresCertificateTransparency
- NSAllowsLocalNetworking
目录
- ATS Configuration Basics / ATS 配置基础知识
- Using ATS in Apple Frameworks / 在 Apple 框架中使用 ATS
- Availability of ATS for Remote and Local Connections / 本地 & 远程连接与 ATS
- Requirements for Connecting Using ATS / 使用 ATS 的前提条件
- Certificate Transparency
- ATS and Overriding HTTPS Server Trust Evaluation / ATS 与改写服务端信任评估规则
- App Store Review for ATS / App Store 对于 ATS 相关项的审核
- ATS Dictionary Details / ATS 字典详细信息
- ATS Examples / ATS 配置实例
- Debugging ATS Connections / ATS Debugging 相关
- Using the nscurl Tool to Diagnose ATS Connection Issues / 使用 nscurl 工具诊断 ATS 相关问题
ATS Configuration Basics / ATS 配置基础知识
对于使用 iOS9.0, OS X v10.11 SDK 及以上的 app 来说,ATS(App Transport Security)默认开启,NSAllowsArbitraryLoads
是字典NSAppTransportSecurity
的根键,默认值NO
。
在启用 ATS 的情况下,所有的 HTTP 请求必须为 HTTPS(RFC 2818) 连接。任何不安全的 HTTP 请求都将失败。ATS 使用 TLS(Transport Layer Security)v1.2(RFC 5246)。更多关于安全连接的信息,请查阅HTTPS Server Trust Evaluation。
下面是字典NSAppTransportSecurity
的总体结构,所有键都是非必填项:
NSAppTransportSecurity : Dictionary {
NSAllowsArbitraryLoads : Boolean
NSAllowsArbitraryLoadsInMedia : 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
}
}
}
可以看出,所有键可以分为两类:主键,这些键用来定义 app 的总体 ATS 策略;子键,即NSExceptionDomains
下面的键,使用这些键针对某个域名单独配置。
主键包括:
-
NSAllowsArbitraryLoads
- 设置为 YES,解除整个 app 的 ATS 限制;但是,通过
NSExceptionDomains
进行的配置依然有效。默认值为 NO。 - 注意:设置为 YES,会引发 App Stroe 的审查,开发者必须说明原因。
- 设置为 YES,解除整个 app 的 ATS 限制;但是,通过
-
NSAllowsArbitraryLoadsInMedia
- 设置为 YES,解除通过 AV Foundation 框架访问媒体内容时的 ATS 限制;启用这个键,务必确保载入的媒体内容已经被加密,例如受
FairPlay
保护的文件,或者是安全的HLS
流媒,其中不包含敏感的个人信息。默认为 NO。
- 设置为 YES,解除通过 AV Foundation 框架访问媒体内容时的 ATS 限制;启用这个键,务必确保载入的媒体内容已经被加密,例如受
-
NSAllowsArbitraryLoadsInWebContent
- 设置为 YES,解除通过 web view 发出的网络请求的 ATS 限制。启用这个键,可以使 app 访问任意网页内容,但不影响 app 的总体 ATS 策略。此键值默认为 NO。
-
NSAllowsLocalNetworking
- 设置为 YES,使得 app 可以载入任意本地资源,但不影响 app 的总体 ATS 策略。默认为 NO。
-
NSExceptionDomains
- 为一个或多个域名单独配置 ATS。
- 被单独配置的域名,默认受到完全的 ATS 限制,不管
NSAllowsArbitraryLoads
的值如何;需要通过子键,进一步配置。
阅读表2,获取关于上述主键的详细信息。
所有的子键都属于NSExceptionDomain
。向Info.plist
中添加这一主键:
- 创建字典,针对一个或多个域名,以便进行 ATS 配置。
- 这意味着之前使用主键所做的设置,对于这个域名来说,已经无效。
例如,及时之前设置NSAllowsArbitraryLoadsInMedia
为 YES,然而NSExceptionDomain
所代表的域名依然不能访问不安全的媒体内容。
基于这样的设定,可以针对域名进行 ATS 配置,增加或减少安全措施。例如:
- 将
NSExceptionAllowsInsecureHTTPLoads
设置为 YES,就 ;这样做会引发 App Store 的审查,详情见App Store Review for ATS。 - 通过配置
NSExceptionRequiresForwardSecrecy
为 NO,取消正向保密。 - 通过配置
NSExceptionMinimumTLSVersion
,更改 TLS 最低版本。
还参考Certificate Transparency
,保证访问特定域名时的安全,详情见Certificate Transparency。
NSExceptionDomains
字典构成:
- <域名字符串>
- 代表想要配置的特定域名。可以添加多个域名(即添加多个这样的键),为它们统一配置 ATS 策略。这个键对应一个字典,包含以下子键:
- NSIncludesSubdomains
- 设置为 YES,当前域名的 ATS 策略适用于其所有子域名。默认为 NO。
- NSExceptionAllowsInsecureHTTPLoads
- 设置为 YES,可以同时通过 HTTP 和 HTTPS 访问当前域名。默认为 NO。
- 注意,配置这个键值,将引发 App Store 的审查,开发者必须说明原因。
- NSExceptionMinimumTLSVersion
- 指定 TLS 的最低版本,因此可以使用版本较低,有安全漏洞的 TLS 协议。
- 注意,配置这个键值,将引发 App Store 的审查,开发者必须说明原因。
- NSExceptionRequiresForwardSecrecy
- 设置为 NO,允许针对当前域名使用不支持正向保密的 TLS 加密算法。默认为 YES。
- NSRequiresCertificateTransparency
- 设置为 YES,将验证域名服务器证书的
Certificate Transparency
时间戳 。默认为 NO。
- 设置为 YES,将验证域名服务器证书的
- NSIncludesSubdomains
- 代表想要配置的特定域名。可以添加多个域名(即添加多个这样的键),为它们统一配置 ATS 策略。这个键对应一个字典,包含以下子键:
阅读表3,获取关于NSExceptionDomains
的进一步详细信息。
Using ATS in Apple Frameworks / 在 Apple 框架中使用 ATS
NSURLSession 以及所有与其相关的 API 都实现了对 ATS 的支持;如果您的 app 基于 iOS9.0 SDK 或 OS X v10.11 SDK 以上版本开发,ATS 自动开启。(较老的 NSURLConnection 同样会在上述 SDK 中开启对 ATS 的支持。)然而,在使用底层网络 API 或第三方网络库时,无法受到 ATS 的保护。
**注意**:使用底层 API 或第三方网络库时,请仔细考量风险因素。
iOS9.0 或 OS X v10.11 以下版本,不支持 ATS,NSAppTransportSecurity
会被操作系统忽略。当 ATS 不可用时,系统将根据RFC 2818提供标准的 HTTPS 安全策略,对服务端进行验证。
当您的 app 运行在 iOS9.0 或者 OS X v10.11以下时,网络连接仍然可用,但 ATS 不起作用。
Availability of ATS for Remote and Local Connections / 本地 & 远程与 ATS
ATS 只针对公共域名
起效。ATS 对已下连接无效:
- IP 地址
- 非法域名
- 使用
.local
作为顶级域名的本地主机
为了连接非法域名或本地域名,需要将NSAllowsLocalNetworking
设置为 YES。
**注意**:虽然本地连接并不强制使用 ATS,但 Apple 强烈推荐开发者通过TLS + 自签名证书的方式访问本地连接。
Requirements for Connecting Using ATS / 使用 ATS 的前提条件
在 ATS 完全开启的情况下,系统要求 app 的 HTTPS 连接必须满足以下要求:
-
X.509 数字证书必须满足下列标准中的一项:
- 由操作系统内嵌的根证书颁发机构签发
- 由通过操作系统管理员或用户主动安装的根证书颁发机构签发
TLS 版本必须为1.2,任何不使用或使用较低版本 TLS / SSL 的连接,都将失败。
-
连接必须使用 AES-128 或 AES-256 对称加密算法。 TLS 算法套装必须以 ECDSA 密钥交换的形式支持正向保密,加密算法必须为下面之一:
- 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
-
服务端的叶证书签名密钥必须为下面之一:
- 至少2048位的 RSA 密钥
- 至少256位的 ECC 密钥
- 此外,服务器证书的哈希算法必须为 SHA-2,其摘要长度至少位256位(即 SHA-256 及以上)。
上面的标准,未来可能会发生变化。但不会影响到 app 二进制包的兼容性。
Certificate Transparency
暂略
ATS and Overriding HTTPS Server Trust Evaluation / ATS 和 改写服务器授信校验规则
能否自行改写服务器授信校验规则,取决于 ATS 是否针对某个域名开启。解释如下:
- 如果 ATS 针对域名开启,无法改写。
- 如果 ATS 未针对域名开启,系统将按照默认规则进行授信校验,可以改写。
App Store Review for ATS / App Store 对于 ATS 相关项的审核
某些对 ATS 的配置会引发 App Store 的审核,开发者必须说明原因。这些键有:
- NSAllowsArbitraryLoads
- NSExceptionAllowsInsecureHTTPLoads
- NSExceptionMinimumTLSVersion
以下是一些原因说明例子,供参考:
- 必须连接由其他机构控制的服务器,其还不支持安全连接。
- 必须支持那些还未升级至可使用安全连接,不得不通过公共域名访问网络的设备。
- 必须通过 web 展示来源不一的各种网络内容,但又不能完全使用
NSAllowsArbitraryLoadsInWebContent
所管理的类。
向 App Store 提交审核时,开发者应主动提供足够的信息,以便解释 app 无法使用安全连接的原因。
ATS Dictionary Details / ATS 字典详细信息
表2列出了NSAppTransportSecurity
字典所有主键信息,通过定义这些主键,开发者可以配置 app 的网络行为。同NSExceptionDomains
相关的子键信息请查看表3。
表2 ATS 字典主键
键名 | Xcode 描述名 |
类型 | 描述 |
---|---|---|---|
NSAllowsArbitraryLoads | “Allow Arbitrary Loads” | Boolean | 非必填项,设置为 YES,关闭 ATS,通过NSExceptionDomains 配置的域名除外。使用这个键将引发 App Store 的审核,开发者必须说明原因。 这个键有助于开发和 debug。 iOS10 或 macOS 10.12 以上系统中,如果下列键出现在 info.plist 中,这个键的值将被忽略:<li> NSAllowsArbitraryLoadsForMediaContent<li> NSAllowsArbitraryLoadsInWebContent<li> NSAllowsLocalNetworking注意,关闭 ATS, 所有的网络连接(HTTP / HTTPS)不再受到限制;可以使用低版本的 TLS 协议;可以使用不支持正向保密的加密算法。 默认值为 NO,表示对所有连接采用默认的 ATS 策略,通过 NSExceptionDomains 进行配置的域名除外。 |
NSAllowsArbitraryLoadsInMedia | 无 | Boolean | 非必填项,设置为 YES ,关闭对于通过 AV Foundation 框架访问的媒体内容的 ATS 限制,详情见AV Foundation Framework Reference。 仅在媒体内容已经被加密,如受到 FairPlay 保护;或者播放安全的 HLS 流媒体;并且不包含个人信息时启用这个键。 如果 info.plist 包含这个键,不管它的值是什么,ATS 都将忽略 NSAllowsArbitraryLoads 的值。这个键的默认值为 NO。 iOS10.0 和 macOS 10.12 及以上可用。 |
NSAllowsArbitraryLoadsInWebContent | 无 | Boolean | 非必填项,只针对下列类有效:<li>WKWebView<li>UIWebView(iOS)<li>WebView(macOS) 当设置为 YES 时,app 的 web 视图进行内容访问时可以不受 ATS 限制,同时不影响其他诸如 NSURLSession 的安全策略。默认值为 NO。 为了支持旧版本的 iOS 和 OS X,可以使用这键的同时,手动配置 ATS:将这个键的值设置为 YES,同时配置 NSAllowsArbitraryLoads 子键。如果 info.plist 包含这个键,不论其值如何, NSAllowsArbitraryLoads 的值将被忽略。iOS10.0 和 macOS 10.12 及以上可用。 |
NSAllowsLocalNetworking | 无 | Boolean | 非必填项,设置为 YES,移除所有针对非法域名和.local 开头的域名的 ATS 限制,对于其他域名没有影响。如果设置为 YES, NSAllowsArbitraryLoads 的值将被忽略(iOS10.0 和 macOS 10.12以后)。这种设定使得 app 的内置本地浏览器在以前的版本仍旧正常工作,同时在新的版本获得完整的 ATS 保护。(设置方法:将这个键设置为 YES,并且将NSAllowsArbitraryLoads 也设置为 YES)。默认值为 NO。 iOS10.0 和 macOS 10.12 及以上可用。 |
NSExceptionDomains | “Exception Domains” | Boolean | 非必填项,针对某个域名单独配置 ATS 策略。这个字典中的每个键都对应一个字典,用来描述针对特定域名的网络安全策略。 最上层的键是域名字符串;例如,www.apple.com,其必须符合以下规范:<li>全部小写<li>不能包含端口号<li>不能是数字表示的 IP 地址 <li>不能以 . 结尾,除非开发者确定要这样做。例如,example.com. 对应"example.com."(末尾有点),而非example.com 。类似的,example.com 对应"example.com"(末尾无点),而非example.com. 。更多关于此字典的信息,参加表3。 |
表3列举了用来针对某个域名进行网络安全配置所使用的键。
表3 针对某个域名进行网络安全配置的子键
键名 | Xcode 描述名 |
类型 | 描述 |
---|---|---|---|
NSIncludesSubdomains | 无 | Boolean | 非必填项,设置为 YES,当前域名的 ATS 策略适用于其所有子域名。 默认值为 NO。 |
NSRequiresCertificateTransparency | 无 | Boolean | 非必填项,设置为 YES,将验证域名服务器证书的Certificate Transparency 时间戳。默认值为 NO。 iOS10.0 和 macOS 10.12 及以上可用。 |
NSExceptionAllowsInsecureHTTPLoads | 无 | Boolean | 非必填项,设置为 YES,将允许不安全的网络连接,但不改变 TLS 策略。如果确定域名足够安全,可以使用这个键。 使用这个键将引发 App Store 的审核,开发者必须说明原因。 设置为 YES,app 可以针对当前域名同时使用 HTTP 连接和 HTTPS 连接;不安全的访问形式包括:证书缺失,自签名,过期,证书不符等。 可能需要启用这个键的情形:<li>需要通过不安全的连接访问当前域名<li>访问无法进行授信校验的服务器<li>访问 HTTPS 服务器,但需要改写服务器授信校验规则 有时,这个键需要配合其他键使用。例如,需要安全连接一个自签名服务器,或者服务器 TLS 版本低于1.2,这时,将 NSExceptionAllowsInsecureHTTPLoads 设置为 YES,然后将NSExceptionMinimumTLSVersion 设置为合适的值即可。默认值为 NO。 |
NSExceptionRequiresForwardSecrecy | 无 | Boolean | 非必填项,用来表示是否要求服务器支持正向保密。如果确定域名足够安全,可以使用这个键。 默认值为 YES,即将符合要求的加密算法限制在ATS Configuration Basics中。 设置为 NO,则可以接受以下加密算法形式:<li>TLS_RSA_WITH_AES_256_GCM_SHA384<li>TLS_RSA_WITH_AES_128_GCM_SHA256<li>TLS_RSA_WITH_AES_256_CBC_SHA256<li>TLS_RSA_WITH_AES_256_CBC_SHA<li>TLS_RSA_WITH_AES_128_CBC_SHA256<li>TLS_RSA_WITH_AES_128_CBC_SHA |
NSExceptionMinimumTLSVersion | 无 | String | 非必填项,用来表示可用的 TLS 最低版本。如果确定域名足够安全,可以使用这个键。 使用这个键将引发 App Store 的审核,开发者必须说明原因。 可用的值有:<li>TLSv1.0<li>TLSv1.1<li>TLSv1.2 默认值为 TLSv1.2。 |
ATS Examples / ATS 配置实例
下面介绍NSAppTransportSecurity
的常见配置:
针对特定服务器使用 HTTP 连接
不影响整体 ATS 策略,只针对特定服务器进行不安全的网络请求——例如,从图片服务器请求图片——可在Info.plist
中做如下配置:
NSAppTransportSecurity
NSExceptionDomains
"media-server.example.com"
NSExceptionAllowsInsecureHTTPLoads = YES
重要:使用上述配置之前,请注意其可能带来的潜在威胁。例如,通过 HTTP 连接从服务器获取媒体资源,可能带来如下风险:
- 攻击者可以获悉用户所访问的媒体资源内容
- 加大了 app 的受攻击面,攻击者可以通过恶意文件使得缓冲区溢出,从而造成 app 异常
针对特定服务器降低安全防护等级
不影响整体 ATS 策略,只针对特定服务器降低 HTTPS 的安全等级——包括使用较老版本的 TLS / SSL 协议,不支持正向保密——可在Info.plist
中做如下配置:
NSAppTransportSecurity
NSExceptionDomains
"less-secure.example.com"
NSExceptionRequiresForwardSecrecy = NO
NSExceptionMinimumTLSVersion = "TLSv1.0"
针对受控服务器使用 HTTPS 连接,其他服务器使用 HTTP 连接
假设正在开发一款浏览器应用,需要能够让用户访问任意 URL。这种情况下,开发者应该针对受控服务器使用安全连接,例如用于发布 app 更新的服务器。
为了能够让针对受控服务器的访问享受 ATS 保护,同时保证其他不安全访问可用,可在Info.plist
中做如下配置:
NSAppTransportSecurity
NSExceptionDomains
"domain-i-control.example.com"
NSExceptionAllowsInsecureHTTPLoads = NO
NSExceptionRequiresForwardSecrecy = YES
NSExceptionMinimumTLSVersion = "TLSv1.2"
"other-domain-i-control.example.com"
NSExceptionAllowsInsecureHTTPLoads = NO
NSExceptionRequiresForwardSecrecy = YES
NSExceptionMinimumTLSVersion = "TLSv1.2"
NSAllowsArbitraryLoads = YES
Debugging ATS Connections / ATS Debugging 相关
暂略
Using the nscurl Tool to Diagnose ATS Connection Issues / 使用 nscurl 工具诊断 ATS 相关问题
暂略