HTTPS接口加密和身份認(rèn)證

? 對(duì)HTTPS研究有一段時(shí)間了,在這里寫下一些收集的資料和自己的理解。有不對(duì)的地方希望斧正。


1.為什么要使用HTTPS代替HTTP

1.1HTTPS和HTTP的區(qū)別

1)https協(xié)議需要到CA申請(qǐng)證書,一般免費(fèi)證書很少,需要交費(fèi)。

2)http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的SSL加密傳輸協(xié)議。

3)http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。

4)http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。


1.2http為什么不安全

? ?http協(xié)議沒有任何的加密以及身份驗(yàn)證的機(jī)制,非常容易遭遇竊聽、劫持、篡改,因此會(huì)造成個(gè)人隱私泄露,惡意的流量劫持等嚴(yán)重的安全問題。

? ?就像寄信一樣,我給你寄信,中間可能會(huì)經(jīng)過很多的郵遞員,他們可以拆開信讀取里面的內(nèi)容,因?yàn)槭敲魑牡摹H绻愕男爬锷婕暗搅四銈冦y行賬號(hào)等敏感信息,可能就會(huì)被竊取。除此之外,郵遞員們還可以給你偽造信的內(nèi)容,導(dǎo)致你遭到欺騙。


1.3https如何保證安全

? ?HTTPS是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。它是一個(gè)URI scheme(抽象標(biāo)識(shí)符體系),句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸。https:URL表明它使用了HTTPS,但HTTPS存在不同于HTTP的默認(rèn)端口及一個(gè)加密/身份驗(yàn)證層(在HTTP與TCP之間)。這個(gè)系統(tǒng)的最初研發(fā)由網(wǎng)景公司進(jìn)行,提供了身份驗(yàn)證與加密通訊方法,現(xiàn)在它被廣泛用于萬維網(wǎng)上安全敏感的通訊,例如交易支付方面。


2.HTTPS的加密原理

2.1首先先介紹一些加密過程中用到的原理:

2.1.1對(duì)稱加密

? ?對(duì)稱加密是指加密和解密使用相同密鑰的加密算法。它要求發(fā)送方和接收方在安全通信之前,商定一個(gè)密鑰。對(duì)稱算法的安全性依賴于密鑰,泄漏密鑰就意味著任何人都可以對(duì)他們發(fā)送或接收的消息解密,所以密鑰的保密性對(duì)通信至關(guān)重要。

對(duì)稱加密算法的優(yōu)、缺點(diǎn):

優(yōu)點(diǎn):算法公開、計(jì)算量小、加密速度快、加密效率高。

缺點(diǎn):1)交易雙方都使用同樣鑰匙,安全性得不到保證;

? ? ? ? 2)每對(duì)用戶每次使用對(duì)稱加密算法時(shí),都需要使用其他人不知道的惟一鑰匙,這會(huì)使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級(jí)數(shù)增長,密鑰管理成為用戶的負(fù)擔(dān)。

? ? ? ? 3)能提供機(jī)密性,但是不能提供驗(yàn)證和不可否認(rèn)性。


2.1.2非對(duì)稱加密算法

這種加密或許理解起來比較困難,這種加密指的是可以生成公鑰和私鑰。凡是公鑰加密的數(shù)據(jù),公鑰自身不能解密,而需要私鑰才能解密;凡是私鑰加密的數(shù)據(jù),私鑰不能解密,需要公鑰才能解密。這種算法事實(shí)上有很多,常用的是RSA,其基于的數(shù)學(xué)原理是兩個(gè)大素?cái)?shù)的乘積很容易算,而拿到這個(gè)乘積去算出是哪兩個(gè)素?cái)?shù)相乘就很復(fù)雜了,具體原理有興趣可以自行研究。

非對(duì)稱加密相比對(duì)稱加密更加安全,但也存在兩個(gè)明顯缺點(diǎn):

? ? ? ?1)CPU計(jì)算資源消耗非常大。一次完全TLS握手,密鑰交換時(shí)的非對(duì)稱解密計(jì)算量占整個(gè)握手過程的90%以上。而對(duì)稱加密的計(jì)算量只相當(dāng)于非對(duì)稱加密的0.1%,如果應(yīng)用層數(shù)據(jù)也使用非對(duì)稱加解密,性能開銷太大,無法承受。

? ? ? ?2)非對(duì)稱加密算法對(duì)加密內(nèi)容的長度有限制,不能超過公鑰長度。比如現(xiàn)在常用的公鑰長度是2048位,意味著待加密內(nèi)容不能超過256個(gè)字節(jié)。

? ?所以公鑰加密目前只能用來作密鑰交換或者內(nèi)容簽名,不適合用來做應(yīng)用層傳輸內(nèi)容的加解密。

2.1.3身份認(rèn)證(CA數(shù)字證書)

? ?https協(xié)議中身份認(rèn)證的部分是由數(shù)字證書來完成的,證書由公鑰、證書主體、數(shù)字簽名等內(nèi)容組成,在客戶端發(fā)起SSL請(qǐng)求后,服務(wù)端會(huì)將數(shù)字證書發(fā)給客戶端,客戶端會(huì)對(duì)證書進(jìn)行驗(yàn)證,并獲取用于秘鑰交換的非對(duì)稱密鑰。

數(shù)字證書有兩個(gè)作用:

1,身份授權(quán)。確保瀏覽器訪問的網(wǎng)站是經(jīng)過CA驗(yàn)證的可信任的網(wǎng)站。

2,分發(fā)公鑰。每個(gè)數(shù)字證書都包含了注冊(cè)者生成的公鑰。在SSL握手時(shí)會(huì)通過certificate消息傳輸給客戶端。

申請(qǐng)一個(gè)受信任的數(shù)字證書通常有如下流程:

1,終端實(shí)體(可以是一個(gè)終端硬件或者網(wǎng)站)生成公私鑰和證書請(qǐng)求。

2,RA(證書注冊(cè)及審核機(jī)構(gòu))檢查實(shí)體的合法性。如果個(gè)人或者小網(wǎng)站,這一步不是必須的。

3,CA(證書簽發(fā)機(jī)構(gòu))簽發(fā)證書,發(fā)送給申請(qǐng)者。

4,證書更新到repository(負(fù)責(zé)數(shù)字證書及CRL內(nèi)容存儲(chǔ)和分發(fā)),終端后續(xù)從repository更新證書,查詢證書狀態(tài)等。

數(shù)字證書驗(yàn)證:

申請(qǐng)者拿到CA的證書并部署在網(wǎng)站服務(wù)器端,那瀏覽器發(fā)起握手接收到證書后,如何確認(rèn)這個(gè)證書就是CA簽發(fā)的呢?怎樣避免第三方偽造這個(gè)證書?答案就是數(shù)字簽名(digital signature)。數(shù)字簽名是證書的防偽標(biāo)簽,目前使用最廣泛的SHA-RSA(SHA用于哈希算法,RSA用于非對(duì)稱加密算法)數(shù)字簽名的制作和驗(yàn)證過程如下:

1)數(shù)字簽名的簽發(fā)。首先是使用哈希函數(shù)對(duì)待簽名內(nèi)容進(jìn)行安全哈希,生成消息摘要,然后使用CA自己的私鑰對(duì)消息摘要進(jìn)行加密。

2)數(shù)字簽名的校驗(yàn)。使用CA的公鑰解密簽名,然后使用相同的簽名函數(shù)對(duì)待簽名證書內(nèi)容進(jìn)行簽名并和服務(wù)端數(shù)字簽名里的簽名內(nèi)容進(jìn)行比較,如果相同就認(rèn)為校驗(yàn)成功。

需要注意的是:

1)數(shù)字簽名簽發(fā)和校驗(yàn)使用的密鑰對(duì)是CA自己的公私密鑰,跟證書申請(qǐng)者提交的公鑰沒有關(guān)系。

2)數(shù)字簽名的簽發(fā)過程跟公鑰加密的過程剛好相反,即是用私鑰加密,公鑰解密。

3)現(xiàn)在大的CA都會(huì)有證書鏈,證書鏈的好處一是安全,保持根CA的私鑰離線使用。第二個(gè)好處是方便部署和撤銷,即如果證書出現(xiàn)問題,只需要撤銷相應(yīng)級(jí)別的證書,根證書依然安全。

4)根CA證書都是自簽名,即用自己的公鑰和私鑰完成了簽名的制作和驗(yàn)證。而證書鏈上的證書簽名都是使用上一級(jí)證書的密鑰對(duì)完成簽名和驗(yàn)證的。

5)怎樣獲取根CA和多級(jí)CA的密鑰對(duì)?它們是否可信?當(dāng)然可信,因?yàn)檫@些廠商跟瀏覽器和操作系統(tǒng)都有合作,它們的公鑰都默認(rèn)裝到了瀏覽器或者操作系統(tǒng)環(huán)境里。

2.2加密的詳細(xì)過程

? ?首先服務(wù)器端用非對(duì)稱加密(RSA)產(chǎn)生公鑰和私鑰。然后把公鑰發(fā)給客 戶端,路徑或許有人會(huì)截取,但是沒有用,因?yàn)橛霉€加密的文件只有私鑰可以解密,而私鑰永遠(yuǎn)都不會(huì)離開服務(wù)器的。當(dāng)公鑰到達(dá)客戶端之后,客戶端會(huì)用對(duì)稱加密產(chǎn)生一個(gè)秘鑰并且用公鑰來加密發(fā)送給服務(wù)器端,這個(gè)秘鑰就是以后用來通信的鑰匙。這樣服務(wù)器端收到公鑰加密的秘鑰時(shí)就可以用私鑰來解公鑰從而獲得秘鑰。這樣的話客戶端和服務(wù)器端都獲得了秘鑰,信息交流相對(duì)是安全的。流程圖如下:

? ?聽起來確實(shí)是挺安全的,但實(shí)際上,還有一種更惡劣的攻擊是這種方法無 ? 法防范的,這就是傳說中的“中間人攻擊”。在身份認(rèn)證的過程中,出現(xiàn)了一個(gè)“中間人”攔截我們的信息,他有意想要知道你們的消息。我們將這個(gè)中間人稱為M。當(dāng)服務(wù)器第一次給客戶端發(fā)送公鑰的時(shí)候,途徑M。M知道你要進(jìn)行密鑰交換了,它把公鑰扣了下來,假裝自己是客戶端,偽造了一個(gè)偽秘鑰(對(duì)稱加密產(chǎn)生的),然后用服務(wù)器發(fā)來的公鑰加密了偽秘鑰發(fā)還給服務(wù)器,這樣服務(wù)器以為和客戶端完成了密鑰交換,實(shí)際上服務(wù)器是和M完成了密鑰交換(獲得了偽秘鑰)。同時(shí)M假扮成服務(wù)器自行用非對(duì)稱加密產(chǎn)生偽公鑰和偽私鑰,與客戶端進(jìn)行秘鑰交換,拿到客戶端發(fā)送過來的秘鑰。現(xiàn)在客戶端拿著秘鑰,M拿著秘鑰和為偽秘鑰,服務(wù)器拿著偽秘鑰,整個(gè)交流的過程就是:

簡單點(diǎn)說就是:

1)客戶端用秘鑰加密信息發(fā)送給M;

2)M收到后用秘鑰解密拿到信息,然后用偽秘鑰加密信息發(fā)送給服務(wù)器;

3)服務(wù)器收到后用偽秘鑰解密拿到信息。

這樣中間人M就拿到了客戶端和服務(wù)器所有的交流信息。

? ?對(duì)于這種攻擊,我們可以加上身份認(rèn)證:這個(gè)時(shí)候就要引入CA證書,CA證書的原理可回到2.1.3。數(shù)字證書中包括的主要內(nèi)容有:證書擁有者的個(gè)人信息、證書擁有者的公鑰、公鑰的有效期、頒發(fā)數(shù)字證書的CA、CA的數(shù)字簽名等。所以網(wǎng)上雙方經(jīng)過相互驗(yàn)證數(shù)字證書后,不用再擔(dān)心對(duì)方身份的真?zhèn)危梢苑判牡嘏c對(duì)方進(jìn)行交流或授予相應(yīng)的資源訪問權(quán)限。

? ?通俗一點(diǎn)理解就是,服務(wù)器端把公鑰交個(gè)CA證書,CA證書再包裝一層。(具體原理請(qǐng)回看2.3)然后再發(fā)給客戶端,這個(gè)包裝一層的意思是:保證這個(gè)證書是我(服務(wù)器)給你(客戶端的),其他人拿到了也沒有用。

? ?最后,你可能會(huì)想既然非對(duì)稱加密可以那么安全,為什么我們不直接用它來加密信息,而是用來加密對(duì)稱加密的密鑰呢?

? ?這是因?yàn)榉菍?duì)稱加密的密碼對(duì)生成和加密的消耗時(shí)間比較長,為了節(jié)省雙方的計(jì)算時(shí)間,通常只用它來交換密鑰,而非直接用來傳輸數(shù)據(jù)(具體的可看上文非對(duì)稱加密的缺點(diǎn))。

3.使用AFNetworking進(jìn)行雙向認(rèn)證

3.1客戶端認(rèn)證服務(wù)器端證書

如上圖所示客戶端想要認(rèn)證服務(wù)器,首先需要和服務(wù)端的數(shù)字證書匹配(server.cer),具體方法如下。

1)在項(xiàng)目中導(dǎo)入證書sever.cer和AFNetworking框架:

2)然后到AFSecurityPolicy.m中重寫+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode方法:

demo

? ?AFNetworking2是允許內(nèi)嵌證書的,通過內(nèi)嵌證書,AFNetworking2通過比對(duì)服務(wù)器端證書、內(nèi)嵌的證書、站點(diǎn)域名是否一致來驗(yàn)證連接的服務(wù)器是否正確。在完成以上兩條的情況下,會(huì)自動(dòng)掃描bundle中.cer的文件,并引入,這樣就可以通過自簽證書來驗(yàn)證服務(wù)器唯一性了。

3.2服務(wù)器端認(rèn)證客戶端

1)服務(wù)端驗(yàn)證客戶端證書,首先把服務(wù)端的證書client.p12導(dǎo)入到服務(wù)端的密鑰庫里,同時(shí)導(dǎo)入工程;

2)在AFURLConnectionOperation.m中加入以下方法:

demo

3)重寫AFURLConnectionOperation.m中的- (void)connection:(NSURLConnection*)connection

? ?如果是需要認(rèn)證的時(shí)候不會(huì)先調(diào)用didReceiveResponse,而是先調(diào)用3)和2)的函數(shù),NSURLAuthenticationChallenge是一個(gè)認(rèn)證挑戰(zhàn)類,也就是要求客戶端進(jìn)行挑戰(zhàn),要接收挑戰(zhàn)也就是客戶端提供挑戰(zhàn)的憑證(用戶和密碼,或者客戶端證書,或者信任服務(wù)器證書,或者代理),IOS提供了一個(gè)NSURLCredential的類來表示挑戰(zhàn)憑證。可以通過如下函數(shù)來建立挑戰(zhàn)憑證。所以訪問https的時(shí)候服務(wù)器認(rèn)證客戶端就調(diào)用這個(gè)方法。

? ?這兩段代碼是通過p12文件來驗(yàn)證服務(wù)器的,需要自己修改的地方只有一個(gè),那就是2)中的CFStringRefpassword =CFSTR("123456");這是p12證書的密碼,用自己的p12證書密碼替換"123456"。

4.3控制器里如何請(qǐng)求

通過4.1和4.2我們的客戶端和服務(wù)器雙向認(rèn)證已經(jīng)設(shè)置好了,在控制器里只需要需要調(diào)用manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];的方法來進(jìn)行雙向認(rèn)證:

然后就可以訪問HTTPS的服務(wù)器了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容