自2017年1月1日起,提交到App Store的所有APP必须遵循ATS(App Transport Security)。也就是说,应用内的网络连接必须使用安全连接。
前言##
HTTPS最初由网景公司使用,在HTTP应用层使用SSL协议保证数据安全,故称HTTPS。随着SSL的发展,演变为TSL。具体区别和联系可以参照这篇Blog——SSL与TLS 区别以及介绍。本文主要讲述如何在iOS中适配,对于HTTPS原理不多做解释。这里需要强调的是TSL 1.2以上的HTTPS是完全正向保密(Perfect Forward Secrecy)的,而1.2以前的版本则存在以后被破解的风险。这一点涉及到后面的APP配置,需要留意。
设置Info.plist##
为了适配iOS9下的HTTP请求,很多人在Info.plist中做了如下设置。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
如今HTTP即将成为历史,这个设置也大可以删掉。
如果你使用TSL 1.2(含)以上的HTTPS连接,是无需设置的。如果你使用1.2以下的HTTPS连接,还需要做以下设置。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>domain-name-string</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
这里还有一个NSIncludesSubdomains用于配置允许子域名访问的,可以按需设置。
代理中处理证书##
这里使用Swift2.3(与Swift2.2几乎一样),日后可能更新Swift3的代码。在NSURLSession的delegate里,做如下处理。
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
completionHandler(.UseCredential, credential)
}
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
completionHandler(.Allow)
}
Tips##
使用如下指令可以不同参数下查询ATS状态。
➜ ~ /usr/bin/nscurl --ats-diagnostics --verbose https://apple.com