蘋果新『應(yīng)用通信安全』的理解和使用
這篇文章是對WWDC大會中提出的App Transport Security(應(yīng)用通訊安全)模式的解讀,蘋果在 App Transport Security Technote 中也進行了解讀。
隨著iOS 9和OS X EI Capitan 的發(fā)布,蘋果官方引入了應(yīng)用通訊安全模式的概念。簡而言之,應(yīng)用通訊安全模式強制性要求應(yīng)用需要使用***的安全通訊協(xié)議,比如TLS 1.2版本和前向保密技術(shù)。在不久的將來,蘋果也將更新這些***實踐以確保他們在保障網(wǎng)絡(luò)數(shù)據(jù)安全的潮流中走在前列。
在iOS 9 和 OS X EI Caption之后,當使用NSURLSession的時候默認會開啟ATS。然而不幸的是,對于大多數(shù)開發(fā)者而言,這將意味著在他們基于新版本的操作系統(tǒng)做開發(fā)時,情況有了很大的變化。好消息是,蘋果官方提供了一些可選配置項來決定是否開啟ATS模式,也就是可以選擇開啟或者不開啟。
開發(fā)者可以針對某些確定的URL不使用ATS,這需要在工程中的info.plist中標記NSExceptionDomains。在NSExceptionDomains字典中,可以顯式的指定一些不使用ATS的URL。這些你可以使用的例子可以是:
- NSIncludesSubdomains
- NSExceptionAllowInsecureHTTPLoads
- NSExceptionRequiresForwardSecrecy
- NSExceptionMinimumTLSVersion
- NSThirdPartyExceptionAllowsInsecureHTTPLoads
- NSThirdPartyExceptionMinimumTLSVersion
- NSThirdPartyExceptionRequiresForwardSecrecy
這些關(guān)鍵字使我們可以更加細致的設(shè)置針對不使用ATS的域名情況下禁用ATS或者一些特殊的ATS選項。
**在iOS 9 的beta1版本中,上述的關(guān)鍵字是錯誤的,應(yīng)該使用如下關(guān)鍵字:**
- NSTemporaryExceptionAllowsInsecureHTTPLoads
- NSTemporaryExceptionRequiresForwardSecrecy
- NSTemporaryExceptionMinimumTLSVersion
- NSTemporaryThirdPartyExceptionAllowsInsecureHTTPLoads
- NSTemporaryThirdPartyExceptionMinimumTLSVersion
- NSTemporaryThirdPartyExceptionRequiresForwardSecrecy
這些關(guān)鍵字在不久以后肯定會被替換掉。如果可以,你應(yīng)該使用***組的關(guān)鍵字,因為蘋果官方支持這些關(guān)鍵字。雖然你正在使用臨時的關(guān)鍵字,但它應(yīng)該在將來的beta版本中還是可以繼續(xù)使用的。
下面是一些開發(fā)者可能會在開發(fā)過程中遇到的情況。
例1 所有情況下都使用ATS
這是最簡單的情況。唯一需要做的事情就是使用NSURLSession。如果你的開發(fā)目標是iOS 9或者 OS X EI Capitan之后,ATS的***實踐將會應(yīng)用到所有基于NSURLSession的網(wǎng)絡(luò)。
例2 特殊情況除外,都使用ATS
如果你希望自己所有的域名,除了一些已知并不會使用ATS之外的,所有通信都使用ATS。這種情況下你可以指定一些不使用ATS的特殊情況,而其余的情況使用ATS。對于這種場景,可以使用*NSExceptionDomains*來標識使用ATS默認設(shè)置的域。為了篩選出所有域或者子域,可以創(chuàng)建一個包含想要排除使用ATS的URL的字典,然后設(shè)置其中的*NSExceptionAllowInsecureHTTPLoads*的值為true。如果想要對于這些域完全禁用ATS,也可以指定更多的規(guī)則來限制,如使用*NSExceptionRequiresForwardSecrecy*和*NSExceptionMinimumTLSVersion*關(guān)鍵字。
例3 除特殊情況外,都不使用ATS
一種與上例相反的情況,你可能進希望在你明確知道支持的域內(nèi)使用ATS。比如,如果開發(fā)一個Twitter客戶端,可能需要有難以計數(shù)的可能不支持ATS的URL需要加載,可是你希望網(wǎng)絡(luò)狀況想發(fā)起登錄請求和請求Twitter服務(wù)器的其他請求一致。在這種情況下,你可以設(shè)置禁用ATS為默認選項,然后指定需要使用ATS的URL。
這種情況下,需要設(shè)置*NSAllowArbitraryLoads*為true,然后在*NSExceptionDomains*字典中定義需要保證安全性的URL。需要保證安全性的每個域都需要有自己的字典,而且字典中的*NSExceptionAllowInsecureHTTPLoads*選項需要設(shè)置為false。
例4 低級的ATS
在某些情況下,可能ATS用于所有情況,或者一些,或者是自有的URL,但是并未針對所有的ATS***實踐全部支持。也許你的應(yīng)用服務(wù)器僅支持TLS1.2,但是不支持之后的版本,與其把涉及到的所有域都設(shè)置為不用ATS,不如設(shè)置為支持版本較低的ATS。這種場景下,需要創(chuàng)建一個*NSExceptionDomains*字典,這是一個對于每個域都要重用的字典選項,然后設(shè)置*NSExceptionRequiresForwardSecrecy*值為false。類似的,如果你希望向前支持,但是需要***版本的TLS,你可以通過*NSExceptionMinimumTLSVersion*關(guān)鍵字定義你的應(yīng)用服務(wù)器所支持的TLS版本。
例5 NSA-friendly 模式
如果想完全不使用ATS(不建議使用這種模式,并且需要你完全理解其隱藏的危險。)你可以在info.plist中設(shè)置*NSAllowArbitraryLoads*屬性為true。
第三方鍵值
你可能注意到一些關(guān)鍵字像是使用了一些其他關(guān)鍵字中的詞但是在前面加上了"ThirdParty"字樣:
- NSThirdPartyExceptionAllowsInsecureHTTPLoads
- NSThirdPartyExceptionMinimumTLSVersion
- NSThirdPartyExceptionRequiresForwardSecrecy
在功能上,這些關(guān)鍵字與不含有"ThirdParty"的關(guān)鍵字有同樣的效果。而且實際運行中所調(diào)用的代碼將會完全忽略是否使用"ThirdParty"關(guān)鍵字。你應(yīng)該使用適用于你的場景的關(guān)鍵字而不必過多考慮這些。
Certificate Transparency
雖然ATS大多數(shù)安全特性都是默認可用的,Certificate Transparency 是必須設(shè)置的。如果你有支持Certificate Transparency的證書,你可以檢查NSRequiresCertificateTransparency關(guān)鍵字來使用Certificate Transparency。再次強調(diào),如果你的證書不支持Certificate Transparency,此項需要設(shè)置為不可用。
如果需要調(diào)試一些由于采用了ATS而產(chǎn)生的問題,需要設(shè)置CFNETWORK_DIAGNOSTICS為1,這樣就會打印出包含被訪問的URL和ATS錯誤在內(nèi)的NSURLSession錯誤信息。要確保處理了遇到的所有的錯誤消息,這樣才能使ATS易于提高可靠性和擴展性。
以上所有信息都 WWDC 2015 NSURLSession session 中有所體現(xiàn)。***,蘋果強調(diào)需要上報開發(fā)過程所有的問題并且需要密切關(guān)注將來beta版本中的可能產(chǎn)生的變化。