iOS9中新增App Transport Security(簡稱ATS)特性, 主要使到原來請求的時候用到的HTTP青团,都轉(zhuǎn)向TLS1.2協(xié)議進行傳輸。這也意味著所有的HTTP協(xié)議都強制使用了HTTPS協(xié)議進行傳輸糟袁。原文如下:
App Transport Security
App Transport Security (ATS) enforces best practices in the secure connections between an app and its back end. ATS prevents accidental disclosure, provides secure default behavior, and is easy to adopt; it is also on by default in iOS 9 and OS X v10.11. You should adopt ATS as soon as possible, regardless of whether you’re creating a new app or updating an existing one.
If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn't follow this requirement, an error is thrown. If your app needs to make a request to an insecure domain, you have to specify this domain in your app'sInfo.plistfile
如果我們在iOS9下直接進行HTTP請求是會收到如下錯誤提示:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
系統(tǒng)會告訴我們不能直接使用HTTP進行請求,需要在Info.plist新增一段用于控制ATS的配置:
NSAppTransportSecurity
NSAllowsArbitraryLoads
也即:
這段配置中的NSAppTransportSecurity是ATS配置的根節(jié)點泊业,配置了節(jié)點表示告訴系統(tǒng)要走自定義的ATS設置油讯。而NSAllowsAritraryLoads節(jié)點則是控制是否禁用ATS特性,設置YES就是禁用ATS功能田弥。
直到前面的配置可以完美的適配iOS9了涛酗,但是如果你想遵循蘋果給出的標準,讓自己的數(shù)據(jù)更加安全,那么需要繼續(xù)往下看商叹。
其實ATS并不單單針對HTTP進行了限制燕刻,而是對HTTPS也有一定的要求,以百度的地址為例剖笙,如果在App中請求https://baidu.com的話卵洗,是會收到如下的錯誤信息:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
查閱了一下官方資料(https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/),發(fā)現(xiàn)HTTPS的請求需要滿足下面的要求:
These are the App Transport Security requirements:
The protocol Transport Security Layer (TLS) must be at least version 1.2.
Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
Certificates must use at least an SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256 bit or greater Elliptic-Curve (ECC) key.
根 據(jù)原文描述弥咪,首先必須要基于TLS 1.2版本協(xié)議过蹂。再來就是連接的加密方式要提供Forward Secrecy(正向保密?這個不清楚是什么聚至,好奇的筒子找資料吧~)酷勺,文檔中羅列出支持的加密算法(如下表)。最后就是證書至少要使用一個SHA256 的指紋與任一個2048位或者更高位的RSA密鑰扳躬,或者是256位或者更高位的ECC密鑰脆诉。如果不符合其中一項,請求將被中斷并返回nil坦报。
支持Forward Secrecy的加密方式
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
我們再來看剛才的百度的地址库说,用瀏覽器打開百度的地址,然后點擊鏈接前面的鎖圖標片择,如圖:
可以看到它使用了TLS 1.2版本協(xié)議,符合第一個約定骚揍。然后可以看到使用AES_128_GCM進行加密字管,并使用ECDHE_RSA作為密鑰交換機制的,我們可以在Forward Secrecy的列表中找到對應兩條記錄:
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
但是還不能確定百度是否提供Forward Secrecy信不,我們再點開證書信息嘲叔,查看“簽發(fā)者名稱”和“公共密鑰信息”兩項,如圖:
看到簽名算法中寫著“帶RSA加密的SHA-1”抽活×蚋辏可以判定該加密算法不包含在上面兩項中。因此百度是一個不符合ATS的要求下硕,所以返回了錯誤丁逝。這時候,如果要解決這樣的問題梭姓,同樣需要對ATS進行配置霜幼。配置如下:
NSAppTransportSecurity? ? ? ? ? ? NSExceptionDomains? ? ? ? ? ? ? ? ? ? baidu.com? ? ? ? ? ? ? ? ? ? ? ? ? ? NSIncludesSubdomains? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSExceptionRequiresForwardSecrecy? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NSExceptionAllowsInsecureHTTPLoads? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
其中NSIncludesSubdomains設置為YES表示百度的子級域名都使用相同設置。 NSExceptionRequiresForwardSecrecy為NO由于百度不支持ForwardSecrecy誉尖,因此屏蔽掉改功能罪既。最后 NSExceptionAllowInsecureHTTPLoads設置為YES,則表示允許訪問沒有證書或者是自簽名、過期琢感、主機名不匹配的證書引發(fā) 的錯誤的域名(這里檢查過百度的證書貌似沒有什么問題丢间,但是還是需要設置此項才允許訪問)。