升級到了xCode7,第一次打開工程,雖然有了心理準備,但是心理仍然拔涼拔涼的.
幾十個error(Swift1.2->2.0).修改完畢后,興匆匆的Command+R,登陸失敗=.=.
經(jīng)過一番查找,原來是ATS的鍋,于是有了ATS的學習筆記.
ATS
也就是App Transport Security,略顯高大上的名字.意思就是說從iOS9開始會默認使用https進行數(shù)據(jù)訪問.沒有經(jīng)過配置的工程使用http的時候無法訪問數(shù)據(jù).
當然ATS有一些獨特的要求(Server):
- Transport Layer Security協(xié)議版本要求TLS1.2以上
- 服務的Ciphers配置要求支持Forward Secrecy等
- 證書簽名算法符合ATS要求等
感覺好麻煩,我們更關心到底怎么辦~是全面修改為https還是想辦法適配http呢?
蘋果提供了4種處理策略,通過Plist進行配置
- 全部使用https
- 部分使用https
- 部分不使用https
- 全部不使用https
策略1:需要符合ATS的相關規(guī)范
策略2:在plist中配置列表:哪些需要用到https
策略3:在plist中配置例外的列表:那些不需要https
策略4:在plist中申明則http又可以工作啦~所以...
相關plist關鍵字涉及到NSAllowsArbitraryLoads等,上方文檔中有較為詳細的介紹.
Https
非官方不準確的理解為加密的http.名字上就是http over s(secure socket layer),也就是信息加密過后的http.
和http相比,https因為信息加過了密,所以優(yōu)勢在于安全,第三方無法截獲(截獲后無法查看),也無法偽造.
當然劣勢在于,性能肯定要差點,因為有加密解密的過程.
ATS使用TSL1.2協(xié)議,https中s的基礎也就是TSL協(xié)議.
主要流程在于客戶端發(fā)送請求前的四次握手,交換證書,隨機數(shù),協(xié)議等.然后通過RSA用公鑰算法生成密鑰,然后通過密鑰加密信息.服務端通過私鑰解開信息的密鑰,然后用密鑰解開信息.
握手階段主要目的在于交換和驗證信息,讓雙方保持可靠.
加密階段分為兩個部分.第一個部分為通訊內(nèi)容加密,使用對稱加密方式,需要一個密鑰.而這個密鑰也需要加密,不然會被人截取,所以使用RSA的方式進行加密.
然后就是普通的http傳輸了.既然是http傳輸,那么信息當然可以被截取.不過截取到的信息因為加過密,所以第三方也讀不懂,也沒辦法偽造,所以就安全了.
握手
- 客戶端告訴服務端:我的協(xié)議版本(ATS需要TSL1.2),我的加密方式(RSA),我的隨機數(shù)(第一個隨機數(shù))
- 服務端收到了以后,告訴客戶端:確認協(xié)議版本(如果不支持客戶端的協(xié)議版本,則通信關閉),確認加密方式,服務端的隨機數(shù)(第二個隨機數(shù)),證書
- 客戶端會收到證書,證書非常重要,其中包含了服務端的公鑰(RSA相關).然后告訴服務端:一切ok,準備通信,在發(fā)送一個隨機數(shù)(第三個隨機數(shù))
- 服務端收到了隨機數(shù)后,通過以上3個隨機數(shù),生成了一個密鑰,發(fā)送給了客戶端.而這個密鑰就是隨后加密通信內(nèi)容的密鑰.
剩下的就是http通信了,只是將通信內(nèi)容通過這個密鑰加密了.
有個小小的問題,為什么要有3個隨機數(shù),服務端自己生成一個不可以嗎?
原因是目前隨機數(shù)算法都是偽隨機,一旦隨機數(shù)算法被破解,那么一切都可能會被破解.而三個隨機數(shù)作用起來,被破解的可能性就非常小了.
加密
加密分為2個部分,握手階段最重要的事情就是生成一個密鑰,用來加密通信內(nèi)容.
而有了這個密鑰,通信內(nèi)容通過對稱加密的方式加密,然后就是普通的http方式傳輸了.
那么問題來了,為什么需要用2種加密方式呢.
生成密鑰通過RSA,加密通訊內(nèi)容使用DES.
- 無法單獨使用RSA的原因是:該方法一是非常慢,因為其加密原理.二是對加密內(nèi)容有一定要求,無法加密過長的內(nèi)容.(實際上不是這個意思,加密內(nèi)容是把內(nèi)容轉(zhuǎn)為ascii碼,太長會導致這個ascii碼組成的數(shù)字太大,RSA無法加密太大的數(shù)字.)
- 無法單獨使用DES加密的原因是:因為傳輸過程中,是http.所以密鑰在傳輸過程中是明文,會被獲取.
所以結合雙方有點使用,完美的解決了這個問題.
RSA
非對稱加密的一種算法.具體數(shù)學原理參考:
略顯復雜.
大概意思就是說,這種算法有一個公鑰,一個密鑰.公鑰公開,私鑰自己拿著.通過公鑰加密的東西可以用私鑰解開,通過私鑰加密的東西也可以通過公鑰解開.
這種算法安全的原因是基于一個比較基礎的原理:人類目前暫時很難分解2個很大的素數(shù)的乘積.1024位2進制的私鑰基本安全,2048位的私鑰就目前而言是非常安全的.
所以在TSL中,通過該方法使用公鑰加密DES的密鑰,那么密鑰就非常安全了.然后通過私鑰解開這個加密過后的密鑰,就能拿到密鑰本身了.在通過密鑰本身,就能解開信息內(nèi)容本身了.
問題又來了,既然是需要通過公鑰來加密,那么公鑰在哪里?
在證書里.在握手的時候,服務端會給客戶端證書,證書就包含了公鑰.
證書
通過證書包含的公鑰以及服務端的私鑰,可以確保通信內(nèi)容的加密解密.
問題繼續(xù)來,為什么一定要給個證書呢,直接給公鑰不行么?
不行.
公鑰私鑰只能證明這一套配套,能互相解開對方加密的信息.但是沒有辦法證明這個公鑰屬于誰.或許服務器被入侵,公鑰私鑰被人替換了,也無法得知.
所以就有了數(shù)字證書這個東西.找個第三方(CA)公正,把你的私人信息(公鑰)進行加密,做成一張數(shù)字證書.用什么東西加密?用第三方(CA)的私鑰.
當然,這件事情是要收費的...
操作系統(tǒng)等會有一個CA的信任列表,使用CA的公鑰解開數(shù)字證書,再通過列表對比,則會確認該證書是否是偽造的.