[Updated in 2016.12.22],苹果ATS大限时间推迟,参照Apple News and Updates - Supporting App Transport Security,具体实行时间可继续关注News and Updates。
[Updated in 2016.12.09],苹果官网文档2016年11月14日更新,修改NSAllowsArbitraryLoadsInMedia为NSAllowsArbitraryLoadsForMedia,参考Document Revision History,下面文档已修改。
App Transport Security(ATS) 是Apple为增强iOS App网络通信安全提出的安全功能,适用于iOS App和App Extension;在启用ATS之后,它会强制应用通过HTTPS(而不是HTTP)连接网络服务。
WWDC 2016上提出,2016年底或2017年初(准确实行时间可关注News and Updates),App Store上架审核加强对ATS配置的review,即强制应用必须通过HTTPS连接网络服务,而不是随手将NSAllowsArbitraryLoads置为YES,否则审核不予通过(当然也有例外,下文会讲述),当前已知的审核策略可见2.3节; 【注意】这仅是App Store审核策略的变更,而不是技术上的限制,即App通过ATS相应配置仍可以通过HTTP进行网络访问(测试时可使用)。在App的Info.plist中进行ATS相关属性配置,ATS相关NSAppTransportSecurity如下,所有属性都是可选的,更详细的属性配置说明可参考ATS Dictionary Details。
【注意】NSAllowsArbitraryLoadsInMedia,苹果官网文档2016年11月14日更新,修改为NSAllowsArbitraryLoadsForMedia,参考Document Revision History,下面文档已修改。 NSAppTransportSecurity : Dictionary { NSAllowsArbitraryLoads : Boolean NSAllowsArbitraryLoadsForMedia : Boolean NSAllowsArbitraryLoadsInWebContent : Boolean NSAllowsLocalNetworking : Boolean NSExceptionDomains : Dictionary { <domain-name-string> : Dictionary { NSIncludesSubdomains : Boolean NSExceptionAllowsInsecureHTTPLoads : Boolean NSExceptionMinimumTLSVersion : String NSExceptionRequiresForwardSecrecy : Boolean NSRequiresCertificateTransparency : Boolean } } } NSAllowsArbitraryLoads,默认值为NO,置为YES后,所有网络请求不受ATS的限制; NSAllowsArbitraryLoadsForMedia,默认值为NO,置为YES后,使用AV Foundation框架载入资源时不受ATS的限制;(iOS 10.0及以上支持,测试发现真机可行,模拟器未起作用) NSAllowsArbitraryLoadsInWebContent,默认值为NO,置为YES后,使用web view的网络请求不受ATS限制;(iOS 10.0及以上支持) NSAllowsLocalNetworking,默认值为NO,置为YES后,本地网络请求不受ATS限制;(iOS 10.0及以上支持)NSExceptionDomains,配置特定域名的ATS访问属性;
NSIncludesSubdomains,默认值为NO,置为YES后,该域名的ATS配置适用于其子域名; NSExceptionAllowsInsecureHTTPLoads,默认值为NO,置为YES后,该域名可通过HTTP请求访问但TLS版本要求不会改变; NSExceptionMinimumTLSVersion,默认值为TLSv1.2,设置该域名支持的TLS最低版本,有效值:TLSv1.0、TLSv1.1和TLSv1.2; NSExceptionRequiresForwardSecrecy,默认值为YES,置为NO后,访问该域名时TLS ciphers可以不支持完全正向保密(PFS); NSRequiresCertificateTransparency,默认值为NO,置为YES后,访问该域名时服务器证书需要有效的SCT(signed Certificate timestamps)。【注意】NSAllowsArbitraryLoads 、NSAllowsArbitraryLoadsForMedia、NSAllowsArbitraryLoadsInWebContent和NSExceptionAllowsInsecureHTTPLoads 任一属性置为YES或设置NSExceptionMinimumTLSVersion,都会触发App Store的额外审核并需要提交对应说明(详情见2.3节)。NSURLConnection/NSURLSession相关及任何基于此的上层API;
经测试,基于IP访问的HTTP请求(使用NSURLConnection/NSURLSession),在iOS 9系统上受ATS限制;但在iOS 10系统上不受ATS限制,可以正常访问。iOS 9.0+系统支持,低于iOS 9.0系统忽略NSAppTransportSecurity的配置。使用Apple底层网络API或第三方网络库API,不受ATS限制。当ATS要求全部使能时,HTTPS网络连接需要满足下面要求:
X.509证书必须至少满足下面一种条件:
由根证书是操作系统安装的CA颁发;由用户或系统管理员信任并安装的根证书颁发;TLS版本必须为TLS 1.2,不使用TLS或使用老版本TLS的连接,访问会失败,基于TLSTool工程可获取服务器支持的TLS相关参数;连接必须使用AES-128或AES-256对称加密算法,TLS协商算法必须通过ECDHE密钥交换保证完全正向保密(Perfect Forward Secrecy, PFS),ECDHE密钥必须属于下面一种: 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密钥;Apple官方给出的可以通过审核的声明demo如下:
必须使用第三方提供的服务,但是其没有支持HTTPS;必须通过域名连接到设备,但该设备不能支持安全连接;必须展示不同来源的网页内容,但是不能基于NSAllowsArbitraryLoadsInWebContent支持的类(UIWebView / WKWebView)实现;载入加密的媒体资源并且其中不涉及个人信息。由于Apple官方并没有给出ATS审核的完整说明,ATS审核时什么才是合适合理的声明也没有明确的客观定义,以上demo描述仅能作为参照;为保险起见,建议尽快按照Apple要求进行HTTPS适配。使用Apple上层网络API(NSURLConnection/NSURLSession)的HTTP访问,
基于域名访问的请求,需要按照按照2.1节描述进行HTTPS适配;基于IP访问的请求,在iOS 10系统可以不受ATS限制正常访问,建议同样进行HTTPS适配。使用Apple底层网络API进行的网络请求无需进行HTTPS适配。
尽可能地按照要求完成HTTPS的适配,若应用场景必须进行ATS exceptions的配置(比如,浏览器应用必须同时支持HTTP/HTTPS载入、强依赖的第三方服务没有支持HTTPS访问等),保证ATS exceptions配置最小化,App审核时按照2.3节描述给出合理的解释声明。
HTTPS适配完成后,可以先使用/usr/bin/nscurl(OS X v10.11及以上系统支持)工具模拟进行ATS网络连接状况诊断,命令如下:
/usr/bin/nscurl --ats-diagnostics [--verbose] URL连接指定URL时,
--ats-diagnostics参数的设定,会模拟ATS属性的不同配置场景(NSAllowsArbitraryLoads、NSExceptionMinimumTLSVersion、NSExceptionRequiresForwardSecrecy和NSExceptionAllowsInsecureHTTPLoads的不同组合)进行连接; --verbose指定时,可显示ATS不同配置场景的详细信息。例,检测阿里云官网www.aliyun.com
> /usr/bin/nscurl --ats-diagnostics --verbose https://www.aliyun.com Starting ATS Diagnostics Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://www.aliyun.com. A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error. ================================================================================ Default ATS Secure Connection --- ATS Default Connection ATS Dictionary: { } Result : PASS --- ================================================================================ Allowing Arbitrary Loads --- Allow All Loads ATS Dictionary: { NSAllowsArbitraryLoads = true; } Result : PASS --- ================================================================================ Configuring TLS exceptions for www.aliyun.com --- TLSv1.2 ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.2"; }; }; } Result : PASS --- --- TLSv1.1 ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.1"; }; }; } Result : PASS --- --- TLSv1.0 ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.0"; }; }; } Result : PASS --- ================================================================================ Configuring PFS exceptions for www.aliyun.com --- Disabling Perfect Forward Secrecy ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- ================================================================================ Configuring PFS exceptions and allowing insecure HTTP for www.aliyun.com --- Disabling Perfect Forward Secrecy and Allowing Insecure HTTP ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionAllowsInsecureHTTPLoads = true; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- ================================================================================ Configuring TLS exceptions with PFS disabled for www.aliyun.com --- TLSv1.2 with PFS disabled ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.2"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- --- TLSv1.1 with PFS disabled ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.1"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- --- TLSv1.0 with PFS disabled ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionMinimumTLSVersion = "TLSv1.0"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- ================================================================================ Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for www.aliyun.com --- TLSv1.2 with PFS disabled and insecure HTTP allowed ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionAllowsInsecureHTTPLoads = true; NSExceptionMinimumTLSVersion = "TLSv1.2"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- --- TLSv1.1 with PFS disabled and insecure HTTP allowed ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionAllowsInsecureHTTPLoads = true; NSExceptionMinimumTLSVersion = "TLSv1.1"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- --- TLSv1.0 with PFS disabled and insecure HTTP allowed ATS Dictionary: { NSExceptionDomains = { "www.aliyun.com" = { NSExceptionAllowsInsecureHTTPLoads = true; NSExceptionMinimumTLSVersion = "TLSv1.0"; NSExceptionRequiresForwardSecrecy = false; }; }; } Result : PASS --- ================================================================================ATS审核策略还未正式公布,存在变动的可能,上述分析仅供参考。
相关资源:https简单自签记录,苹果ATS检测通过.log