版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.03.01 |
前言
我們做APP發(fā)起網(wǎng)絡(luò)請(qǐng)求券时,都離不開一個(gè)非常有用的框架AFNetworking矩距,可以說(shuō)這個(gè)框架的知名度已經(jīng)超過(guò)了蘋果的底層網(wǎng)絡(luò)請(qǐng)求部分肥印,很多人可能不知道蘋果底層是如何發(fā)起網(wǎng)絡(luò)請(qǐng)求的瘩绒,但是一定知道
AFNetworking
列牺,接下來(lái)幾篇我們就一起詳細(xì)的解析一下這個(gè)框架困肩。感興趣的可以看上面寫的幾篇划纽。
1. AFNetworking源碼探究(一) —— 基本介紹
2. AFNetworking源碼探究(二) —— GET請(qǐng)求實(shí)現(xiàn)之NSURLSessionDataTask實(shí)例化(一)
3. AFNetworking源碼探究(三) —— GET請(qǐng)求實(shí)現(xiàn)之任務(wù)進(jìn)度設(shè)置和通知監(jiān)聽(一)
4. AFNetworking源碼探究(四) —— GET請(qǐng)求實(shí)現(xiàn)之代理轉(zhuǎn)發(fā)思想(一)
5. AFNetworking源碼探究(五) —— AFURLSessionManager中NSURLSessionDelegate詳細(xì)解析(一)
6. AFNetworking源碼探究(六) —— AFURLSessionManager中NSURLSessionTaskDelegate詳細(xì)解析(一)
7. AFNetworking源碼探究(七) —— AFURLSessionManager中NSURLSessionDataDelegate詳細(xì)解析(一)
8. AFNetworking源碼探究(八) —— AFURLSessionManager中NSURLSessionDownloadDelegate詳細(xì)解析(一)
9. AFNetworking源碼探究(九) —— AFURLSessionManagerTaskDelegate中三個(gè)轉(zhuǎn)發(fā)代理方法詳細(xì)解析(一)
10. AFNetworking源碼探究(十) —— 數(shù)據(jù)解析之?dāng)?shù)據(jù)解析架構(gòu)的分析(一)
11. AFNetworking源碼探究(十一) —— 數(shù)據(jù)解析之子類中協(xié)議方法的實(shí)現(xiàn)(二)
12. AFNetworking源碼探究(十二) —— 數(shù)據(jù)解析之子類中協(xié)議方法的實(shí)現(xiàn)(三)
回顧
前面講述了AFN中數(shù)據(jù)的解析機(jī)制,這一篇看一下AFN與HTTPS認(rèn)證锌畸。
HTTPS
以下內(nèi)容來(lái)自百度
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer
)勇劣,是以安全為目標(biāo)的HTTP通道,簡(jiǎn)單講是HTTP的安全版潭枣。即HTTP下加入SSL層比默,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL盆犁。 它是一個(gè)URI scheme(抽象標(biāo)識(shí)符體系)命咐,句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸谐岁。https:URL表明它使用了HTTP醋奠,但HTTPS存在不同于HTTP的默認(rèn)端口及一個(gè)加密/身份驗(yàn)證層(在HTTP與TCP之間)榛臼。這個(gè)系統(tǒng)的最初研發(fā)由網(wǎng)景公司(Netscape)進(jìn)行,并內(nèi)置于其瀏覽器Netscape Navigator中窜司,提供了身份驗(yàn)證與加密通訊方法沛善。
1. HTTP和HTTPS區(qū)別
超文本傳輸協(xié)議HTTP協(xié)議被用于在Web瀏覽器和網(wǎng)站服務(wù)器之間傳遞信息。HTTP協(xié)議以明文方式發(fā)送內(nèi)容例证,不提供任何方式的數(shù)據(jù)加密路呜,如果攻擊者截取了Web瀏覽器和網(wǎng)站服務(wù)器之間的傳輸報(bào)文,就可以直接讀懂其中的信息织咧,因此HTTP協(xié)議不適合傳輸一些敏感信息胀葱,比如信用卡號(hào)、密碼等笙蒙。
為了解決HTTP協(xié)議的這一缺陷抵屿,需要使用另一種協(xié)議:安全套接字層超文本傳輸協(xié)議HTTPS。為了數(shù)據(jù)傳輸?shù)陌踩蔽唬琀TTPS在HTTP的基礎(chǔ)上加入了SSL協(xié)議轧葛,SSL依靠證書來(lái)驗(yàn)證服務(wù)器的身份,并為瀏覽器和服務(wù)器之間的通信加密艇搀。
HTTPS和HTTP的區(qū)別主要為以下四點(diǎn):
- https協(xié)議需要到ca申請(qǐng)證書尿扯,一般免費(fèi)證書很少,需要交費(fèi)焰雕。
- http是超文本傳輸協(xié)議衷笋,信息是明文傳輸,https 則是具有安全性的ssl加密傳輸協(xié)議矩屁。
- http和https使用的是完全不同的連接方式辟宗,用的端口也不一樣,前者是80吝秕,后者是443泊脐。
- http的連接很簡(jiǎn)單,是無(wú)狀態(tài)的烁峭;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸容客、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全约郁。
2. 解決問(wèn)題
- 信任主機(jī)的問(wèn)題
- 通訊過(guò)程中的數(shù)據(jù)的泄密和被篡改
3. SSL
SSL(Secure Sockets Layer
安全套接層),及其繼任者傳輸層安全(Transport Layer Security缩挑,TLS)是為網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。TLS與SSL在傳輸層對(duì)網(wǎng)絡(luò)連接進(jìn)行加密棍现。
SSL (Secure Socket Layer
)為Netscape所研發(fā),用以保障在Internet上數(shù)據(jù)傳輸之安全镜遣,利用數(shù)據(jù)加密(Encryption)技術(shù)己肮,可確保數(shù)據(jù)在網(wǎng)絡(luò)上之傳輸過(guò)程中不會(huì)被截取及竊聽士袄。
SSL協(xié)議位于TCP/IP協(xié)議與各種應(yīng)用層協(xié)議之間,為數(shù)據(jù)通訊提供安全支持谎僻。SSL協(xié)議可分為兩層:SSL記錄協(xié)議(SSL Record Protocol
):它建立在可靠的傳輸協(xié)議(如TCP)之上娄柳,為高層協(xié)議提供數(shù)據(jù)封裝、壓縮艘绍、加密等基本功能的支持赤拒。SSL握手協(xié)議(SSL Handshake Protocol
):它建立在SSL記錄協(xié)議之上,用于在實(shí)際的數(shù)據(jù)傳輸開始前诱鞠,通訊雙方進(jìn)行身份認(rèn)證挎挖、協(xié)商加密算法、交換加密密鑰等航夺。
SSL協(xié)議提供的服務(wù)主要有哪些
- 認(rèn)證用戶和服務(wù)器蕉朵,確保數(shù)據(jù)發(fā)送到正確的客戶機(jī)和服務(wù)器
- 加密數(shù)據(jù)以防止數(shù)據(jù)中途被竊取
- 維護(hù)數(shù)據(jù)的完整性,確保數(shù)據(jù)在傳輸過(guò)程中不被改變阳掐。
SSL協(xié)議的工作流程
-
服務(wù)器認(rèn)證階段:
- 客戶端向服務(wù)器發(fā)送一個(gè)開始信息“Hello”以便開始一個(gè)新的會(huì)話連接始衅;
- 服務(wù)器根據(jù)客戶的信息確定是否需要生成新的主密鑰,如需要?jiǎng)t服務(wù)器在響應(yīng)客戶的“Hello”信息時(shí)將包含生成主密鑰所需的信息缭保;
- 客戶根據(jù)收到的服務(wù)器響應(yīng)信息汛闸,產(chǎn)生一個(gè)主密鑰,并用服務(wù)器的公開密鑰加密后傳給服務(wù)器艺骂;
- 服務(wù)器恢復(fù)該主密鑰诸老,并返回給客戶一個(gè)用主密鑰認(rèn)證的信息,以此讓客戶認(rèn)證服務(wù)器彻亲。
-
用戶認(rèn)證階段:
從SSL 協(xié)議所提供的服務(wù)及其工作流程可以看出轴脐,SSL協(xié)議運(yùn)行的基礎(chǔ)是商家對(duì)消費(fèi)者信息保密的承諾,這就有利于商家而不利于消費(fèi)者抡砂。在電子商務(wù)初級(jí)階段大咱,由于運(yùn)作電子商務(wù)的企業(yè)大多是信譽(yù)較高的大公司,因此這問(wèn)題還沒(méi)有充分暴露出來(lái)注益。但隨著電子商務(wù)的發(fā)展碴巾,各中小型公司也參與進(jìn)來(lái),這樣在電子支付過(guò)程中的單一認(rèn)證問(wèn)題就越來(lái)越突出丑搔。雖然在SSL3.0中通過(guò)數(shù)字簽名和數(shù)字證書可實(shí)現(xiàn)瀏覽器和Web服務(wù)器雙方的身份驗(yàn)證厦瓢,但是SSL協(xié)議仍存在一些問(wèn)題提揍,比如,只能提供交易中客戶與服務(wù)器間的雙方認(rèn)證煮仇,在涉及多方的電子交易中劳跃,SSL協(xié)議并不能協(xié)調(diào)各方間的安全傳輸和信任關(guān)系。在這種情況下浙垫,Visa和MasterCard兩大信用卡公組織制定了SET協(xié)議刨仑,為網(wǎng)上信用卡支付提供了全球性的標(biāo)準(zhǔn)。
4. 握手過(guò)程
為了便于更好的認(rèn)識(shí)和理解SSL 協(xié)議夹姥,這里著重介紹SSL 協(xié)議的握手協(xié)議杉武。SSL 協(xié)議既用到了公鑰加密技術(shù)又用到了對(duì)稱加密技術(shù),對(duì)稱加密技術(shù)雖然比公鑰加密技術(shù)的速度快佃声,可是公鑰加密技術(shù)提供了更好的身份認(rèn)證技術(shù)艺智。SSL 的握手協(xié)議非常有效的讓客戶和服務(wù)器之間完成相互之間的身份認(rèn)證,其主要過(guò)程如下:
①客戶端的瀏覽器向服務(wù)器傳送客戶端SSL 協(xié)議的版本號(hào)圾亏,加密算法的種類十拣,產(chǎn)生的隨機(jī)數(shù),以及其他服務(wù)器和客戶端之間通訊所需要的各種信息志鹃。
②服務(wù)器向客戶端傳送SSL 協(xié)議的版本號(hào)夭问,加密算法的種類,隨機(jī)數(shù)以及其他相關(guān)信息曹铃,同時(shí)服務(wù)器還將向客戶端傳送自己的證書缰趋。
③客戶利用服務(wù)器傳過(guò)來(lái)的信息驗(yàn)證服務(wù)器的合法性,服務(wù)器的合法性包括:證書是否過(guò)期陕见,發(fā)行服務(wù)器證書的CA 是否可靠秘血,發(fā)行者證書的公鑰能否正確解開服務(wù)器證書的“發(fā)行者的數(shù)字簽名”,服務(wù)器證書上的域名是否和服務(wù)器的實(shí)際域名相匹配评甜。如果合法性驗(yàn)證沒(méi)有通過(guò)灰粮,通訊將斷開;如果合法性驗(yàn)證通過(guò)忍坷,將繼續(xù)進(jìn)行第四步粘舟。
④用戶端隨機(jī)產(chǎn)生一個(gè)用于后面通訊的“對(duì)稱密碼”,然后用服務(wù)器的公鑰(服務(wù)器的公鑰從步驟②中的服務(wù)器的證書中獲得)對(duì)其加密佩研,然后將加密后的“預(yù)主密碼”傳給服務(wù)器柑肴。
⑤如果服務(wù)器要求客戶的身份認(rèn)證(在握手過(guò)程中為可選),用戶可以建立一個(gè)隨機(jī)數(shù)然后對(duì)其進(jìn)行數(shù)據(jù)簽名旬薯,將這個(gè)含有簽名的隨機(jī)數(shù)和客戶自己的證書以及加密過(guò)的“預(yù)主密碼”一起傳給服務(wù)器晰骑。
⑥如果服務(wù)器要求客戶的身份認(rèn)證,服務(wù)器必須檢驗(yàn)客戶證書和簽名隨機(jī)數(shù)的合法性绊序,具體的合法性驗(yàn)證過(guò)程包括:客戶的證書使用日期是否有效硕舆,為客戶提供證書的CA 是否可靠隶症,發(fā)行CA 的公鑰能否正確解開客戶證書的發(fā)行CA 的數(shù)字簽名,檢查客戶的證書是否在證書廢止列表(CRL)中岗宣。檢驗(yàn)如果沒(méi)有通過(guò),通訊立刻中斷淋样;如果驗(yàn)證通過(guò)耗式,服務(wù)器將用自己的私鑰解開加密的“預(yù)主密碼”,然后執(zhí)行一系列步驟來(lái)產(chǎn)生主通訊密碼(客戶端也將通過(guò)同樣的方法產(chǎn)生相同的主通訊密碼)趁猴。
⑦服務(wù)器和客戶端用相同的主密碼即“通話密碼”刊咳,一個(gè)對(duì)稱密鑰用于SSL 協(xié)議的安全數(shù)據(jù)通訊的加解密通訊。同時(shí)在SSL 通訊過(guò)程中還要完成數(shù)據(jù)通訊的完整性儡司,防止數(shù)據(jù)通訊中的任何變化娱挨。
⑧客戶端向服務(wù)器端發(fā)出信息,指明后面的數(shù)據(jù)通訊將使用的步驟⑦中的主密碼為對(duì)稱密鑰捕犬,同時(shí)通知服務(wù)器客戶端的握手過(guò)程結(jié)束跷坝。
⑨服務(wù)器向客戶端發(fā)出信息,指明后面的數(shù)據(jù)通訊將使用的步驟⑦中的主密碼為對(duì)稱密鑰碉碉,同時(shí)通知客戶端服務(wù)器端的握手過(guò)程結(jié)束柴钻。
⑩SSL 的握手部分結(jié)束,SSL 安全通道的數(shù)據(jù)通訊開始垢粮,客戶和服務(wù)器開始使用相同的對(duì)稱密鑰進(jìn)行數(shù)據(jù)通訊贴届,同時(shí)進(jìn)行通訊完整性的檢驗(yàn)。
5. SSL證書包含的信息
- 證書版本號(hào)蜡吧,不同版本的證書格式不同
-
Serial Number
序列號(hào)毫蚓,同一身份驗(yàn)證機(jī)構(gòu)簽發(fā)的證書序列號(hào)唯一 -
Algorithm Identifier
簽名算法,包括必要的參數(shù)Issuer 身份驗(yàn)證機(jī)構(gòu)的標(biāo)識(shí)信息 -
Period of Validity
有效期 -
Subject
證書持有人的標(biāo)識(shí)信息 -
Subject’s Public Key
證書持有人的公鑰 -
Signature
身份驗(yàn)證機(jī)構(gòu)對(duì)證書的簽名 - 證書的格式 認(rèn)證中心所發(fā)放的證書均遵循X.509 V3 標(biāo)準(zhǔn)昔善,其基本格式如下:
- 證書版本號(hào)
(Certificate Format Version)
- 含義:用來(lái)指定證書格式采用的X.509 版本號(hào)元潘。
- 證書序列號(hào)
(Certificate Serial Number)
- 含義:用來(lái)指定證書的唯一序列號(hào),以標(biāo)識(shí)CA 發(fā)出的所有公鑰證書耀鸦。
- 簽名
(Signature)
算法標(biāo)識(shí)(Algorithm Identifier)
- 含義:用來(lái)指定 CA 簽發(fā)證書所用的簽名算法柬批。
- 簽發(fā)此證書的 CA 名稱(Issuer )
- 含義:用來(lái)指定簽發(fā)證書的 CA 的X.500 唯一名稱(DN,Distinguished Name)袖订。
- 證書有效期(Validity Period)起始日期(notBefore) 終止日期(notAfter)
- 含義:用來(lái)指定證書起始日期和終止日期氮帐。
- 用戶名稱(Subject)
- 含義:用來(lái)指定證書用戶的X.500 唯一名稱(DN,Distinguished Name)洛姑。
- 用戶公鑰信息
(Subject Public Key Information)
算法(algorithm) 算法標(biāo)識(shí)(Algorithm Identifier)用戶公鑰(subject Public Key)- 含義:用來(lái)標(biāo)識(shí)公鑰使用的算法上沐,并包含公鑰本身。
- 證書擴(kuò)充部分(擴(kuò)展域)(Extensions)
- 含義:用來(lái)指定額外信息楞艾。
X.509 V3 證書的擴(kuò)充部分(擴(kuò)展域)及實(shí)現(xiàn)方法如下:
- CA 的公鑰標(biāo)識(shí)
(Authority Key Identifier)
- 公鑰標(biāo)識(shí)(SET 未使用)
(Key Identifier)
- 簽發(fā)證書者證書的簽發(fā)者的甄別名
(Certificate Issuer)
- 簽發(fā)證書者證書的序列號(hào)
(Certificate Serial Number)
X.509 V3 證書的擴(kuò)充部分(擴(kuò)展域)及實(shí)現(xiàn)CA 的公鑰標(biāo)識(shí)(Authority Key Identifier)
- 公鑰標(biāo)識(shí)(SET 未使用)(Key Identifier)
- 簽發(fā)證書者證書的簽發(fā)者的甄別名(Certificat簽發(fā)證書者證書的序列號(hào)(Certificate Serial Number)
- 含義:CA 簽名證書所用的密鑰對(duì)的唯一標(biāo)識(shí)用戶的公鑰標(biāo)識(shí)(Subject Key Identifier)
- 含義:用來(lái)標(biāo)識(shí)與證書中公鑰相關(guān)的特定密鑰進(jìn)行解密参咙。
- 證書中的公鑰用途
(Key Usage)
- 含義:用來(lái)指定公鑰用途龄广。
- 用戶的私鑰有效期
(Private Key Usage Period)
起始日期(Note Before)
終止日期(Note After)
- 含義:用來(lái)指定用戶簽名私鑰的起始日期和終止日期。
- CA 承認(rèn)的證書政策列表
(Certificate Policies)
- 含義:用來(lái)指定用戶證書所適用的政策蕴侧,證書政策可由對(duì)象標(biāo)識(shí)符表示择同。
- 用戶的代用名
(Substitutional Name)
- 含義:用來(lái)指定用戶的代用名。
- CA 的代用名
(Issuer Alt Name)
- 含義:用來(lái)指定 CA 的代用名净宵。
- 基本制約
(Basic Constraints)
- 證書類型
(Certificate Type)
- 含義:用來(lái)區(qū)別不同的實(shí)體紧武。該項(xiàng)是必選的。
- 商戶數(shù)據(jù)
(Merchant Data)
- 含義:包含支付網(wǎng)關(guān)需要的所有商戶信息敏储。
- 持卡人證書需求
(Card Cert Required)
- 含義:顯示支付網(wǎng)關(guān)是否支持與沒(méi)有證書的持卡人進(jìn)行交易阻星。
- SET 擴(kuò)展
(SETExtensions)
- 含義:列出支付網(wǎng)關(guān)支持的支付命令的 SET 信息擴(kuò)展。
- CRL 數(shù)據(jù)定義版本
(Version)
- 含義:顯示 CRL 的版本號(hào)已添。
- CRL 的簽發(fā)者
(Issuer)
- 含義:指明簽發(fā) CRL 的CA 的甄別名妥箕。
CRL 發(fā)布時(shí)間(this Update)
預(yù)計(jì)下一個(gè) CRL 更新時(shí)間(Next Update)
撤銷證書信息目錄(Revoked Certificates)
CRL 擴(kuò)展(CRL Extension)
CA 的公鑰標(biāo)識(shí)(Authority Key Identifier)
CRL 號(hào)(CRL Number)
SSL證書種類
CFCA,GlobalSign更舞,VeriSign 矾踱,Geotrust ,Thawte
疏哗。
- 域名型 https 證書
(DVSSL)
:信任等級(jí)一般呛讲,只需驗(yàn)證網(wǎng)站的真實(shí)性便可頒發(fā)證書保護(hù)網(wǎng)站; - 企業(yè)型 https 證書
(OVSSL)
:信任等級(jí)強(qiáng)返奉,須要驗(yàn)證企業(yè)的身份贝搁,審核嚴(yán)格,安全性更高芽偏; - 增強(qiáng)型 https 證書
(EVSSL)
:信任等級(jí)最高雷逆,一般用于銀行證券等金融機(jī)構(gòu),審核嚴(yán)格污尉,安全性最高膀哲,同時(shí)可以激活綠色網(wǎng)址欄滨溉。
HTTPS的認(rèn)證過(guò)程
1. 單向認(rèn)證
這個(gè)認(rèn)證過(guò)程可以參考下圖
- 客戶端發(fā)起HTTPS請(qǐng)求
- 直接請(qǐng)求板乙,連接服務(wù)器的443端口
- 服務(wù)端的配置
- 采用HTTPS協(xié)議的服務(wù)器必須要有一套數(shù)字證書咪奖,可以自己制作剧蹂,也可以向組織申請(qǐng)。區(qū)別就是自己頒發(fā)的證書需要客戶端驗(yàn)證通過(guò)殷费,才可以繼續(xù)訪問(wèn)勇婴,而使用受信任的公司申請(qǐng)的證書則不會(huì)彈出提示頁(yè)面蒙幻。這套證書其實(shí)就是一對(duì)公鑰和私鑰。
- 傳送證書
- 這個(gè)證書其實(shí)就是公鑰
- 客戶端解析證書
- 這部分工作是有客戶端的TLS/SSL來(lái)完成的衣迷,首先會(huì)驗(yàn)證公鑰是否有效畏鼓,比如頒發(fā)機(jī)構(gòu),過(guò)期時(shí)間等等壶谒,如果發(fā)現(xiàn)異常云矫,則會(huì)彈出一個(gè)警告框,提示證書存在問(wèn)題汗菜。如果證書沒(méi)有問(wèn)題泼差,那么就生成一個(gè)隨機(jī)值。然后用證書對(duì)該隨機(jī)值進(jìn)行加密呵俏。
- 傳送加密信息
- 這部分傳送的是用證書加密后的隨機(jī)值,目的就是讓服務(wù)端得到這個(gè)隨機(jī)值滔灶,以后客戶端和服務(wù)端的通信就可以通過(guò)這個(gè)隨機(jī)值來(lái)進(jìn)行加密解密了普碎。
- 服務(wù)端解密信息
- 服務(wù)端用私鑰解密后,得到了客戶端傳過(guò)來(lái)的隨機(jī)值(私鑰)录平,然后把內(nèi)容通過(guò)該值進(jìn)行對(duì)稱加密麻车。所謂對(duì)稱加密就是,將信息和私鑰通過(guò)某種算法混合在一起斗这,這樣除非知道私鑰动猬,不然無(wú)法獲取內(nèi)容。
- 傳輸加密后的信息
- 這部分信息是服務(wù)端用私鑰加密后的信息表箭,可以在客戶端被還原赁咙。
- 客戶端解密信息
- 客戶端用之前生成的私鑰解密服務(wù)段傳過(guò)來(lái)的信息,于是獲取了解密后的內(nèi)容免钻。
這里將流程總結(jié)一下:就是用戶發(fā)起請(qǐng)求彼水,服務(wù)器響應(yīng)后返回一個(gè)證書,證書中包含一些基本信息和公鑰极舔。用戶拿到證書后凤覆,去驗(yàn)證這個(gè)證書是否合法,不合法拆魏,則請(qǐng)求終止盯桦。合法則生成一個(gè)隨機(jī)數(shù),作為對(duì)稱加密的密鑰渤刃,用服務(wù)器返回的公鑰對(duì)這個(gè)隨機(jī)數(shù)加密拥峦。然后返回給服務(wù)器。服務(wù)器拿到加密后的隨機(jī)數(shù)卖子,利用私鑰解密事镣,然后再用解密后的隨機(jī)數(shù)(對(duì)稱密鑰),把需要返回的數(shù)據(jù)加密,加密完成后數(shù)據(jù)傳輸給用戶璃哟。最后用戶拿到加密的數(shù)據(jù)氛琢,用一開始的那個(gè)隨機(jī)數(shù)(對(duì)稱密鑰),進(jìn)行數(shù)據(jù)解密随闪。整個(gè)過(guò)程完成阳似。
2. 雙向認(rèn)證
雙向認(rèn)證,相對(duì)于單向認(rèn)證也很簡(jiǎn)單铐伴。僅僅多了服務(wù)端驗(yàn)證客戶端這一步撮奏。感興趣的可以看看這篇:Https單向認(rèn)證和雙向認(rèn)證。
AFSecurityPolicy和認(rèn)證
1. 認(rèn)證過(guò)程和原理
AFN是靠著AFSecurityPolicy
這個(gè)類保證數(shù)據(jù)安全的当宴,調(diào)用下面方法用來(lái)驗(yàn)證是否信任服務(wù)器畜吊。
[self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host])
看一下AFN中的接口
/*!
@typedef SecTrustRef
@abstract CFType used for performing X.509 certificate trust evaluations.
// 執(zhí)行X.509證書信任評(píng)估,其實(shí)就是一個(gè)容器户矢,裝了服務(wù)器端需要驗(yàn)證的證書的基本信息玲献、
公鑰等等,不僅如此梯浪,它還可以裝一些評(píng)估策略捌年,還有客戶端的錨點(diǎn)證書,
這個(gè)客戶端的證書挂洛,可以用來(lái)和服務(wù)端的證書去匹配驗(yàn)證的
*/
typedef struct CF_BRIDGED_TYPE(id) __SecTrust *SecTrustRef;
/**
Whether or not the specified server trust should be accepted, based on the security policy.
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@param domain The domain of serverTrust. If `nil`, the domain will not be validated. // 服務(wù)器域名
@return Whether or not to trust the server.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(nullable NSString *)domain;
根據(jù)安全策略是否接受指定的服務(wù)器信任礼预。 響應(yīng)來(lái)自服務(wù)器的身份驗(yàn)證質(zhì)詢時(shí)應(yīng)使用此方法。
大家還記得這個(gè)代理方法嗎虏劲?
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
//挑戰(zhàn)處理類型為 默認(rèn)
/*
NSURLSessionAuthChallengePerformDefaultHandling:默認(rèn)方式處理
NSURLSessionAuthChallengeUseCredential:使用指定的證書
NSURLSessionAuthChallengeCancelAuthenticationChallenge:取消挑戰(zhàn)
*/
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__block NSURLCredential *credential = nil;
// sessionDidReceiveAuthenticationChallenge是自定義方法托酸,用來(lái)如何應(yīng)對(duì)服務(wù)器端的認(rèn)證挑戰(zhàn)
if (self.sessionDidReceiveAuthenticationChallenge) {
disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential);
} else {
// 此處服務(wù)器要求客戶端的接收認(rèn)證挑戰(zhàn)方法是NSURLAuthenticationMethodServerTrust
// 也就是說(shuō)服務(wù)器端需要客戶端返回一個(gè)根據(jù)認(rèn)證挑戰(zhàn)的保護(hù)空間提供的信任(即challenge.protectionSpace.serverTrust)產(chǎn)生的挑戰(zhàn)證書。
// 而這個(gè)證書就需要使用credentialForTrust:來(lái)創(chuàng)建一個(gè)NSURLCredential對(duì)象
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
// 基于客戶端的安全策略來(lái)決定是否信任該服務(wù)器柒巫,不信任的話获高,也就沒(méi)必要響應(yīng)挑戰(zhàn)
if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
// 創(chuàng)建挑戰(zhàn)證書(注:挑戰(zhàn)方式為UseCredential和PerformDefaultHandling都需要新建挑戰(zhàn)證書)
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
// 確定挑戰(zhàn)的方式
if (credential) {
//證書挑戰(zhàn) 設(shè)計(jì)policy,none,則跑到這里
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
//取消挑戰(zhàn)
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
} else {
//默認(rèn)挑戰(zhàn)方式
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
}
//完成挑戰(zhàn)
if (completionHandler) {
completionHandler(disposition, credential);
}
}
這個(gè)方法是如何進(jìn)行接受挑戰(zhàn)的
- 首先指定了HTTPS為默認(rèn)的認(rèn)證方式吻育。
- 判斷有沒(méi)有自定義Block:
sessionDidReceiveAuthenticationChallenge
念秧,有的話,使用我們自定義Block,生成一個(gè)認(rèn)證方式布疼,并且可以給credential賦值摊趾,即我們需要接受認(rèn)證的證書。然后直接調(diào)用completionHandler
游两,去根據(jù)這兩個(gè)參數(shù)砾层,執(zhí)行系統(tǒng)的認(rèn)證。 - 如果沒(méi)有自定義Block贱案,我們判斷如果服務(wù)端的認(rèn)證方法要求是
NSURLAuthenticationMethodServerTrust
肛炮,則只需要驗(yàn)證服務(wù)端證書是否安全(即https的單向認(rèn)證,這是AF默認(rèn)處理的認(rèn)證方式,其他的認(rèn)證方式侨糟,只能由我們自定義Block的實(shí)現(xiàn)) - 接著我們就執(zhí)行了
AFSecurityPolicy
相關(guān)的上面的方法- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(nullable NSString *)domain
碍扔,關(guān)于這個(gè)方法,AF默認(rèn)的處理是秕重,如果這行返回NO不同、說(shuō)明AF內(nèi)部認(rèn)證失敗,則取消HTTPS認(rèn)證溶耘,即取消請(qǐng)求二拐。返回YES則進(jìn)入if塊,用服務(wù)器返回的一個(gè)serverTrust
去生成了一個(gè)認(rèn)證證書凳兵。(注:這個(gè)serverTrust
是服務(wù)器傳過(guò)來(lái)的百新,里面包含了服務(wù)器的證書信息,是用來(lái)我們本地客戶端去驗(yàn)證該證書是否合法用的庐扫,后面會(huì)更詳細(xì)的去講這個(gè)參數(shù))然后如果有證書饭望,則用證書認(rèn)證方式,否則還是用默認(rèn)的驗(yàn)證方式聚蝶。最后調(diào)用completionHandler
傳遞認(rèn)證方式和要認(rèn)證的證書,去做系統(tǒng)根證書驗(yàn)證藻治。也可以這么理解:這里securityPolicy
存在的作用就是碘勉,使得在系統(tǒng)底層自己去驗(yàn)證之前,AF可以先去驗(yàn)證服務(wù)端的證書桩卵。如果通不過(guò)验靡,則直接越過(guò)系統(tǒng)的驗(yàn)證,取消HTTPS的網(wǎng)絡(luò)請(qǐng)求雏节。否則胜嗓,繼續(xù)去走系統(tǒng)根證書的驗(yàn)證。
2. AFSecurityPolicy實(shí)例化
先看一下該類的實(shí)例化
AFSecurityPolicy *policy = [AFSecurityPolicy defaultPolicy];
+ (instancetype)defaultPolicy {
AFSecurityPolicy *securityPolicy = [[self alloc] init];
securityPolicy.SSLPinningMode = AFSSLPinningModeNone;
return securityPolicy;
}
這里有一個(gè)很重要的屬性就是SSLPinningMode
钩乍,先看一下這個(gè)枚舉
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone, //不驗(yàn)證
AFSSLPinningModePublicKey, //只驗(yàn)證公鑰
AFSSLPinningModeCertificate, // 驗(yàn)證證書
};
下面我們看一下類AFSecurityPolicy的幾個(gè)屬性
/**
The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`.
*/
// 驗(yàn)證模式 這個(gè)枚舉值上面講述過(guò)
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
/**
The certificates used to evaluate server trust according to the SSL pinning mode.
By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.
Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
*/
// 可以去匹配服務(wù)端證書驗(yàn)證的證書
@property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates;
/**
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
*/
// 是否支持非法的證書(例如自簽名證書)
@property (nonatomic, assign) BOOL allowInvalidCertificates;
/**
Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
*/
// 是否去驗(yàn)證證書域名是否匹配
@property (nonatomic, assign) BOOL validatesDomainName;
后記
本篇主要講述了HTTPS認(rèn)證原理以及
AFSecurityPolicy
的實(shí)例化辞州。