前言
HTTP 是基于 TCP/IP 協(xié)議的應(yīng)用層協(xié)議接剩。它不涉及數(shù)據(jù)包(packet)傳輸谣拣,主要規(guī)定了客戶端和服務(wù)器之間的通信格式杠袱,默認(rèn)使用80端口辐怕。但是傳輸?shù)倪^程是通過明文來傳輸铲觉。帶來了三大風(fēng)險
- 竊聽風(fēng)險(eavesdropping):第三方可以獲知通信內(nèi)容澈蝙。
- 篡改風(fēng)險(tampering):第三方可以修改通信內(nèi)容。
- 冒充風(fēng)險(pretending):第三方可以冒充他人身份參與通信撵幽。
在安全問題日益突出的情況下灯荧,互聯(lián)網(wǎng)標(biāo)準(zhǔn)化組織 ISOC 基于 HTTP 協(xié)議通信推出了 SSL/TLS 協(xié)議 也就是 HTTPS , HTTPS 協(xié)議具有
- 所有信息都是加密傳播盐杂,第三方無法竊聽逗载。
- 具有校驗機(jī)制,一旦被篡改链烈,通信雙方會立刻發(fā)現(xiàn)厉斟。
- 配備身份證書,防止身份被冒充强衡。
數(shù)字證書
數(shù)字證書:該證書包含了公鑰等信息捏膨,一般是由服務(wù)器發(fā)給客戶端,接收方通過驗證這個證書是不是由信賴的CA簽發(fā),或者與本地的證書相對比号涯,來判斷證書是否可信目胡;假如需要雙向驗證,則服務(wù)器和客戶端都需要發(fā)送數(shù)字證書給對方驗證链快;
發(fā)展歷史
1994年誉己,NetScape公司設(shè)計了SSL協(xié)議(Secure Sockets Layer)的1.0版,但是未發(fā)布域蜗。
1995年巨双,NetScape公司發(fā)布SSL 2.0版,很快發(fā)現(xiàn)有嚴(yán)重漏洞霉祸。
1996年筑累,SSL 3.0版問世,得到大規(guī)模應(yīng)用丝蹭。
1999年慢宗,互聯(lián)網(wǎng)標(biāo)準(zhǔn)化組織ISOC接替NetScape公司,發(fā)布了SSL的升級版TLS 1.0版奔穿。
2006年和2008年镜沽,TLS進(jìn)行了兩次升級,分別為TLS 1.1版和TLS 1.2版贱田。最新的變動是2011年TLS 1.2的修訂版缅茉。
目前,應(yīng)用最廣泛的是TLS 1.0男摧,接下來是SSL 3.0蔬墩。但是,主流瀏覽器都已經(jīng)實現(xiàn)了TLS 1.2的支持耗拓。
TLS 1.0通常被標(biāo)示為SSL 3.1拇颅,TLS 1.1為SSL 3.2,TLS 1.2為SSL 3.3帆离。
通信原理
握手階段分為 4 個步驟
1、客戶端發(fā)起請求 (ClientHello)
客戶端向服務(wù)器提供
- 支持的協(xié)議版本结澄,比如TLS 1.0版哥谷。
- 一個客戶端生成的隨機(jī)數(shù),稍后用于生成"對話密鑰"麻献。
- 支持的加密方法们妥,比如RSA公鑰加密。
- 支持的壓縮方法勉吻。
2监婶、服務(wù)器回應(yīng) (SeverHello)
服務(wù)器收到 ClientHello, 并作出回應(yīng)。此時服務(wù)器向客戶端發(fā)送
- 確認(rèn)使用的加密通信協(xié)議版本惑惶,比如TLS 1.0版本煮盼。如果瀏覽器與服務(wù)器支持的版本不一致,服務(wù)器關(guān)閉加密通信带污。
- 一個服務(wù)器生成的隨機(jī)數(shù)僵控,稍后用于生成"對話密鑰"。
- 確認(rèn)使用的加密方法鱼冀,比如RSA公鑰加密报破。
- 服務(wù)器證書。
3千绪、客戶端回應(yīng)
客戶端收到服務(wù)器回應(yīng)以后充易,首先驗證服務(wù)器證書。如果證書不是可信機(jī)構(gòu)頒布荸型、或者證書中的域名與實際域名不一致盹靴、或者證書已經(jīng)過期,由其選擇是否還要繼續(xù)通信帆疟。
驗證通過之后客戶端會向服務(wù)端發(fā)送
- 一個隨機(jī)數(shù)(pre-master key)鹉究。該隨機(jī)數(shù)用服務(wù)器公鑰加密,防止被竊聽(服務(wù)器可以通過私鑰來解密出公鑰加密的內(nèi)容)踪宠。
- 編碼改變通知自赔,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送。
- 客戶端握手結(jié)束通知柳琢,表示客戶端的握手階段已經(jīng)結(jié)束绍妨。這一項同時也是前面發(fā)送的所有內(nèi)容的hash值,用來供服務(wù)器校驗柬脸。
4他去、服務(wù)器最后回應(yīng)
服務(wù)器收到客戶端的第三個隨機(jī)數(shù)pre-master key之后,根據(jù)之前的 2 個隨機(jī)數(shù)(ClientHello 和 SeverHello 階段)計算生成本次會話所用的"會話密鑰"倒堕。然后灾测,向客戶端最后發(fā)送下面信息。
- 編碼改變通知垦巴,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送媳搪。
- 服務(wù)器握手結(jié)束通知,表示服務(wù)器的握手階段已經(jīng)結(jié)束骤宣。這一項同時也是前面發(fā)送的所有內(nèi)容的hash值秦爆,用來供客戶端校驗。
傳輸過程
在結(jié)束上面4次握手通信之后憔披,客戶端和服務(wù)端就可以進(jìn)入安全的傳輸過程等限。使用普通的HTTP協(xié)議爸吮,只不過用"會話密鑰"加密解密內(nèi)容。
iOS 中關(guān)于 HTTPS 的驗證
iOS 關(guān)于 HTTPS 驗證的 API 在 Security.Framework 框架中, 在使用 NSURLSession 時
在正規(guī)的 CA 機(jī)構(gòu)申請證書的情況下:
(1) 在回調(diào)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
中我們會收到系統(tǒng)的鑒定請求望门。獲取需要驗證的信任對象(Trust Object)challenge.protectionSpace.serverTrust
(2) 使用系統(tǒng)默認(rèn)驗證方式驗證Trust Object形娇。SecTrustEvaluate
方法會根據(jù)Trust Object的驗證策略,一級一級往上怒允,驗證證書鏈上每一級數(shù)字簽名的有效性埂软,從而評估證書的有效性。
(3) 第二步驗證通過纫事,就可以直接驗證通過勘畔,進(jìn)入到下一步:使用Trust Object生成一份憑證([NSURLCredential credentialForTrust:serverTrust]),調(diào)用 completionHandler(disposition, credential)
來完成鑒勸過程丽惶。
自生成證書的情況下:
需要在第二步之前炫七,調(diào)用SecTrustSetAnchorCertificates
來注冊自己的證書到系統(tǒng)信任列表中,在進(jìn)行上面的第二部過程即可完成校驗钾唬。