關於iOS9中的App Transport Security相關說明及適配

轉載自: http://my.oschina.net/vimfung/blog/494687


iOS9中新增App Transport Security(簡稱ATS)特性, 主要使到原來請求的時候用到的HTTP,都轉向TLS1.2協議進行傳輸。這也意味着所有的HTTP協議都強制使用了HTTPS協議進行傳輸。原文如下:

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's Info.plist file

如果我們在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.

系統會告訴我們不能直接使用HTTP進行請求,需要在Info.plist新增一段用於控制ATS的配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

也即:

這段配置中的NSAppTransportSecurity是ATS配置的根節點,配置了節點表示告訴系統要走自定義的ATS設置。而NSAllowsAritraryLoads節點則是控制是否禁用ATS特性,設置YES就是禁用ATS功能。

直到前面的配置可以完美的適配iOS9了,但是如果你想遵循蘋果給出的標準,讓自己的數據更加安全,那麼需要繼續往下看。

其實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/),發現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.

根據原文描述,首先必須要基於TLS 1.2版本協議。再來就是連接的加密方式要提供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版本協議,符合第一個約定。然後可以看到使用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,我們再點開證書信息,查看“簽發者名稱”和“公共密鑰信息”兩項,如圖:

看到簽名算法中寫着“帶RSA加密的SHA-1”。可以判定該加密算法不包含在上面兩項中。因此百度是一個不符合ATS的要求,所以返回了錯誤。這時候,如果要解決這樣的問題,同樣需要對ATS進行配置。配置如下:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>baidu.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                                <true/>
            </dict>
        </dict>
    </dict>

其中NSIncludesSubdomains設置爲YES表示百度的子級域名都使用相同設置。NSExceptionRequiresForwardSecrecy爲NO由於百度不支持ForwardSecrecy,因此屏蔽掉改功能。最後NSExceptionAllowInsecureHTTPLoads設置爲YES,則表示允許訪問沒有證書或者是自簽名、過期、主機名不匹配的證書引發的錯誤的域名(這裏檢查過百度的證書貌似沒有什麼問題,但是還是需要設置此項才允許訪問)。

發佈了29 篇原創文章 · 獲贊 14 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章