自苹果颁布ATS安全标准以来,ATS广受开发者的大关注。在去年12月初,苹果要求2017年1月1日前,提交到App Store的应用程序要被强制采用ATS协议,否则APP上线将会被拒。这一举措,令众多开发者们措不可及。幸好,在2017年新年即将来临的时候,苹果公司决定延迟实施ATS标准的喜人消息。这无疑让开发者松了一口气,但这并不代表开发者可以解除警惕,毕竟ATS标准仅仅是延迟实施,不代表不执行。所以,早日将自主开发的APP升级,达到ATS标准才是长远之计。
下面介绍一下如何实现支持安全ATS策略以及相关解决方案。
实现支持安全ATS策略
ATS安全标准的相关设置对iOS8及以下系统无效
需要解决的问题(iOS 9、iOS10及以上)
1、app内服务器网络请求访问支持https(即一般的请求)
2、webview内支持任意http访问
3、第三方sdk接入与支持http访问
主要是围绕info.pilst配置文件作相关的安全ATS策略
Info.plist文件是向操作系统描述应用程序的XML属性列表,是iPhone应用程序文件夹包含所有重要的Info.plist文件
你可能注意到一些关键字像是使用了一些其他关键字中的词但是在前面加上了”ThirdParty”字样,在功能上,这些关键字与不含有”ThirdParty”的关键字有同样的效果。而且实际运行中所调用的代码将会完全忽略是否使用”ThirdParty”关键字。
简单粗暴的方案:
--------------------------------------------
NSExceptionDomains 的设置方法如下, 比如我们要将 weibo.com 这个域名排除在 ATS 验证之外,就可以这样:
[objc] view plain copy 在CODE上查看代码片派生到我的代码片
key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>weibo.com</key>
<dict>
<key> NSIncludesSubdomains </key>
<true/>
<key> NSExceptionRequiresForwardSecrecy </key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
注意:每个需添加的域都需要设置此三个属性。如果请求的网络图片是HTTP,也是需要设置的图片的域。
注意️这个方案风险较大,有可能被拒绝。“需要访问的域名是第三方服务器,他们没有进行 HTTPS 对应”会是审核时的一个可选理由,但是这应该只需要针对特定域名,而非全面开放。如果访问的是自己的服务器的话,可能这个理由会无法通过。
------------------------------------------------
实现方案
1、app内服务器网络请求访问支持https
解决方案:
搭建https服务器
搭建https服务器需要SSL证书
ssl自制证书:称自签名ssl证书,容易被假冒伪造,浏览器不信任。(审核不通过)
免费CA证书:部分CA机构提供免费的SSL证书(App Store pass掉不通过)
付费CA证书:多指企业级及以上的数字证书。
HTTPS服务器满足ATS默认的条件,而且SSL证书是通过权威的CA机构认证过的,那么我们在使用Xcode开发的时候,对网络的适配什么都不用做,我们也能正常与服务器通信。但是,当我们对安全性有更高的要求时或者我们自建证书时,我们需要本地导入证书来进行验证。
使用AFNetworking来支持https
AFNetworking是iOS/OSX开发最流行的第三方开源库之一,现在iOS oc 代码90%以上都是用这个框架网络请求。AFNetworking已经将上面的逻辑代码封装好,甚至更完善,在AFSecurityPolicy文件中;以下就是在AFNetworking 2.6.0以前版本和3.0.0版本基于支持https的验证方式
步骤:
新建一个manager
在mainBundle中寻找我们刚才拖进项目中的https.cer, 并且将相关的数据读取出来
新建一个AFSecurityPolicy,并进行相应的配置
将这个AFSecurityPolicy 实例赋值给manager
代码实现:
[objc] view plain copy 在CODE上查看代码片派生到我的代码片
NSURL * url = [NSURL URLWithString:@”https://www.trustauth.cn”];
AFHTTPRequestOperationManager * requestOperationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
dispatch_qwww.shanxiwang.netueue_t requestQueue = dispatch_create_serial_queue_for_name(“kRequestCompletionQueue”);
requestOperationManager.completionQueue = requestQueue;
AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
//如果是需要验证自建证书,需要设置为YES
securityPolicy.allowInvalidCertificates = YES;
//validatesDomainName 是否需要验证域名,默认为YES;
//假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
//置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.trustauth.cn,那么mail.trustauth.cn是无法验证通过的;当然,可以注册通配符的域名*.trustauth.cn。
//如置为NO,建议自己添加对应域名的校验逻辑。
securityPolicy.validatesDomainName = YES;
//validatesCertificateChain 是否验证整个证书链,默认为YES
//设置为YES,会将服务器返回的Trust Object上的证书链与本地导入的证书进行对比,这就意味着,假如你的证书链是这样的:
//GeoTrust Global CA
// Google Internet Authority G2
// *.trustauth.cn
//那么,除了导入*.trustauth.cn之外,还需要导入证书链上所有的CA证书(GeoTrust Global CA, Google Internet Authority G2);
//如是自建证书的时候,可以设置为YES,增强安全性;假如是信任的CA所签发的证书,则建议关闭该验证,因为整个证书链一一比对是完全没有必要(请查看源代码);
securityPolicy.validatesCertificateChain = NO;
requestOperationManager.securityPolicy = securityPolicy;
另afnetworking 3.0.0以上版本用的是AFHTTPSessionManager
AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
NSString * cerPath = [[NSBundle mainBundle] pathForResource:@”server” ofType:@”cer”];
NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
NSLog(@”%@”, cerDwww.hunanwang.netata);
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSArray alloc] initWithObjects:cerData, nil nil]];
manager.securityPolicy.allowInvalidCertificates = YES;
[manager.securityPolicy setValidatesDomainName:NO];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSDictionary * parameter = @{@”username”:self.username, @”password”:self.password};
[manager POST:@”https://192.168.1.4:9777″ parameters:parameter success:^(NSURLSessionDataTask * task, id responseObject) {
NSLog(@”success %@”, responseObject);
}
failure:^(NSURLSessionDataTask * task, NSError * error) {
NSLog(@”failure %@”, error);
}]
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key> //设置为 YES,解除整个app的ATS限制;但是通过NSExceptionDomains进行的配置依然有效
<false/>
<key>NSAllowsArbitraryLoadsInMedia</key> //设置为 YES,解除通过AVFoundation框架访问媒体内容时的 ATS 限制
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key> //设置为 YES,解除通过webview发出的网络请求的ATS限制
<true/>
<key>NSAllowsLocalNetworking</key> //设置为 YES,使得app可以载入任意本地资源,但不影响app的总体 ATS 策略
<true/>
2、webview内支持任意http访问
对于网页浏览和视频播放的行为,iOS 10 中新加入了 NSAllowsArbitraryLoadsInWebContent 键。通过将它设置为 YES,可以让 app 中的 WKWebView 和使用 AVFoundation 播放的在线视频不受 ATS 的限制。这也应该是绝大多数使用了相关特性的 app 的选择。但是坏消息是这个键在 iOS 9 中并不会起作用。
如果app只支持 iOS 10,并且有用户可以自由输入网址进行浏览的功能,或者是在线视频音频播放功能的话,简单地加入 NSAllowsArbitraryLoadsInWebContent,并且将组件换成 WKWebKit 或者 AVFoundation 就可以了。如果你还需要支持 iOS 9,并且需要访问网页和视频的话,可能只能去开启 NSAllowsArbitraryLoads 然后提交时进行说明,并且看 Apple 审核员决定让不让通过了。
另外,当 NSAllowsArbitraryLoads 和 NSAllowsArbitraryLoadsInWebContent 同时存在时,根据系统不同,表现的行为也会不一样。简单说,iOS 9 只看 NSAllowsArbitraryLoads,而 iOS 10 会先看 NSAllowsArbitraryLoadsInWebContent。在 iOS 10 中,要是 NSAllowsArbitraryLoadsInWebContent 存在的话,就忽略掉 NSAllowsArbitraryLoads,如果它不存在,则遵循 NSAllowsArbitraryLoads 的设定
UIWebView 在 NSAllowsArbitraryLoadsInWebContent 为 YES 时访问 HTTP,无效。WKWebView 在 NSAllowsArbitraryLoadsInWebContent 为 YES 时在iOS 10 中访问 HTTP,有效,iOS 9无效。如果用WkWebView替换UIWebView,iOS 7 将无法使用WkWebView,可做适配加载,没有特殊的什么需求的话,尽早将 UIWebView 全部换为 WkWebView 会比较好。所以为了能让WebView在所有版本都能访问非https内容,只能把NSAllowsArbitraryLoads设置为YES。
解决方案一:
开启 NSAllowsArbitraryLoads 为 YES,然后提交时进行说明
解决方案二:
设置 NSExceptionDomains 属性来访问指定域名,然后提交时进行说明
3、第三方sdk接入与支持http访问
但是按照国内的现状,关闭这个限制也许是更实际的做法。至于原因就太多了,第三方SDK(几乎都是访问http),合作伙伴接入(不能要求它们一定要支持https)
第三方sdk,同样需要遵守ATS规则,即第三方sdk也有被ATS过滤的风险。
解决方案一:
更新最新sdk,接入并测试
解决方案二:
可以设置 NSExceptionDomains属性来将需要排除强制验证的域名写进来:
GDCA(数安时代科技股份有限公司)已通过WebTrust EV的国际认证,是全球可信任的证书签发机构。GDCA专业技术团队将根据用户具体情况为其提供最优的产品选择建议,并针对不同的应用或服务器要求提供专业对应的HTTPS解决方案。GDCA签发的SSL证书,均可以达到苹果ATS对证书的硬性标准,帮助App开发商解决这迫在眉睫的服务器安全升级问题。
标签: 苹果ATS Apple ATS 苹果https上一篇:Linux+Tomcat环境下安装SSL证书
下一篇:深入认识苹果ATS安全标准,备战IOS App Stroe审核