本文由CocoaChina译者 lynulzy( 社区ID , 博客 ) 翻译自noir的博客
原文: WORKING WITH APPLE’S APP TRANSPORT SECURITY
中也进行了解读。
随着iOS 9和OS X EI Capitan 的发布,苹果官方引入了应用通讯安全模式的概念。简而言之,应用通讯安全模式强制性要求应用需要使用最佳的安全通讯协议,比如TLS 1.2版本和前向保密技术。在不久的将来,苹果也将更新这些最佳实践以确保他们在保障网络数据安全的潮流中走在前列。
在iOS 9 和 OS X EI Caption之后,当使用NSURLSession的时候默认会开启ATS。然而不幸的是,对于大多数开发者而言,这将意味着在他们基于新版本的操作系统做开发时,情况有了很大的变化。好消息是,苹果官方提供了一些可选配置项来决定是否开启ATS模式,也就是可以选择开启或者不开启。
开发者可以针对某些确定的URL不使用ATS,这需要在工程中的info.plist中标记NSExceptionDomains。在NSExceptionDomains字典中,可以显式的指定一些不使用ATS的URL。这些你可以使用的例子可以是:
- NSIncludesSubdomains
- NSExceptionAllowInsecureHTTPLoads
- NSExceptionRequiresForwardSecrecy
- NSExceptionMinimumTLSVersion
- NSThirdPartyExceptionAllowsInsecureHTTPLoads
- NSThirdPartyExceptionMinimumTLSVersion
- NSThirdPartyExceptionRequiresForwardSecrecy
这些关键字使我们可以更加细致的设置针对不使用ATS的域名情况下禁用ATS或者一些特殊的ATS选项。
**在iOS 9 的beta1版本中,上述的关键字是错误的,应该使用如下关键字:**
- NSTemporaryExceptionAllowsInsecureHTTPLoads
- NSTemporaryExceptionRequiresForwardSecrecy
- NSTemporaryExceptionMinimumTLSVersion
- NSTemporaryThirdPartyExceptionAllowsInsecureHTTPLoads
- NSTemporaryThirdPartyExceptionMinimumTLSVersion
- NSTemporaryThirdPartyExceptionRequiresForwardSecrecy
这些关键字在不久以后肯定会被替换掉。如果可以,你应该使用第一组的关键字,因为苹果官方支持这些关键字。虽然你正在使用临时的关键字,但它应该在将来的beta版本中还是可以继续使用的。
下面是一些开发者可能会在开发过程中遇到的情况。
这是最简单的情况。唯一需要做的事情就是使用NSURLSession。如果你的开发目标是iOS 9或者 OS X EI Capitan之后,ATS的最佳实践将会应用到所有基于NSURLSession的网络。
如果你希望自己所有的域名,除了一些已知并不会使用ATS之外的,所有通信都使用ATS。这种情况下你可以指定一些不使用ATS的特殊情况,而其余的情况使用ATS。对于这种场景,可以使用*NSExceptionDomains*来标识使用ATS默认设置的域。为了筛选出所有域或者子域,可以创建一个包含想要排除使用ATS的URL的字典,然后设置其中的*NSExceptionAllowInsecureHTTPLoads*的值为true。如果想要对于这些域完全禁用ATS,也可以指定更多的规则来限制,如使用*NSExceptionRequiresForwardSecrecy*和*NSExceptionMinimumTLSVersion*关键字。
一种与上例相反的情况,你可能进希望在你明确知道支持的域内使用ATS。比如,如果开发一个Twitter客户端,可能需要有难以计数的可能不支持ATS的URL需要加载,可是你希望网络状况想发起登录请求和请求Twitter服务器的其他请求一致。在这种情况下,你可以设置禁用ATS为默认选项,然后指定需要使用ATS的URL。
这种情况下,需要设置*NSAllowArbitraryLoads*为true,然后在*NSExceptionDomains*字典中定义需要保证安全性的URL。需要保证安全性的每个域都需要有自己的字典,而且字典中的*NSExceptionAllowInsecureHTTPLoads*选项需要设置为false。
在某些情况下,可能ATS用于所有情况,或者一些,或者是自有的URL,但是并未针对所有的ATS最佳实践全部支持。也许你的应用服务器仅支持TLS1.2,但是不支持之后的版本,与其把涉及到的所有域都设置为不用ATS,不如设置为支持版本较低的ATS。这种场景下,需要创建一个*NSExceptionDomains*字典,这是一个对于每个域都要重用的字典选项,然后设置*NSExceptionRequiresForwardSecrecy*值为false。类似的,如果你希望向前支持,但是需要最低版本的TLS,你可以通过*NSExceptionMinimumTLSVersion*关键字定义你的应用服务器所支持的TLS版本。
如果想完全不使用ATS(不建议使用这种模式,并且需要你完全理解其隐藏的危险。)你可以在info.plist中设置*NSAllowArbitraryLoads*属性为true。
你可能注意到一些关键字像是使用了一些其他关键字中的词但是在前面加上了"ThirdParty"字样:
- NSThirdPartyExceptionAllowsInsecureHTTPLoads
- NSThirdPartyExceptionMinimumTLSVersion
- NSThirdPartyExceptionRequiresForwardSecrecy
在功能上,这些关键字与不含有"ThirdParty"的关键字有同样的效果。而且实际运行中所调用的代码将会完全忽略是否使用"ThirdParty"关键字。你应该使用适用于你的场景的关键字而不必过多考虑这些。
虽然ATS大多数安全特性都是默认可用的, Certificate Transparency 是必须设置的。如果你有支持Certificate Transparency的证书,你可以检查NSRequiresCertificateTransparency关键字来使用Certificate Transparency。再次强调,如果你的证书不支持Certificate Transparency,此项需要设置为不可用。
如果需要调试一些由于采用了ATS而产生的问题,需要设置CFNETWORK_DIAGNOSTICS为1,这样就会打印出包含被访问的URL和ATS错误在内的NSURLSession错误信息。要确保处理了遇到的所有的错误消息,这样才能使ATS易于提高可靠性和扩展性。
以上所有信息都 WWDC 2015 NSURLSession session 中有所体现。最后,苹果强调需要上报开发过程所有的问题并且需要密切关注将来beta版本中的可能产生的变化。