? 對HTTPS研究有一段時間了晚伙,在這里寫下一些收集的資料和自己的理解。有不對的地方希望斧正拿愧。
1.為什么要使用HTTPS代替HTTP
1.1HTTPS和HTTP的區(qū)別
1)https協(xié)議需要到CA申請證書,一般免費證書很少,需要交費拾因。
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é)議沒有任何的加密以及身份驗證的機(jī)制图仓,非常容易遭遇竊聽、劫持判耕、篡改透绩,因此會造成個人隱私泄露,惡意的流量劫持等嚴(yán)重的安全問題壁熄。
? ?就像寄信一樣帚豪,我給你寄信,中間可能會經(jīng)過很多的郵遞員草丧,他們可以拆開信讀取里面的內(nèi)容狸臣,因為是明文的。如果你的信里涉及到了你們銀行賬號等敏感信息昌执,可能就會被竊取烛亦。除此之外,郵遞員們還可以給你偽造信的內(nèi)容懂拾,導(dǎo)致你遭到欺騙煤禽。
1.3https如何保證安全
? ?HTTPS是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版岖赋。即HTTP下加入SSL層檬果,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL唐断。它是一個URI scheme(抽象標(biāo)識符體系)选脊,句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸脸甘。https:URL表明它使用了HTTPS恳啥,但HTTPS存在不同于HTTP的默認(rèn)端口及一個加密/身份驗證層(在HTTP與TCP之間)。這個系統(tǒng)的最初研發(fā)由網(wǎng)景公司進(jìn)行丹诀,提供了身份驗證與加密通訊方法钝的,現(xiàn)在它被廣泛用于萬維網(wǎng)上安全敏感的通訊,例如交易支付方面铆遭。
2.HTTPS的加密原理
2.1首先先介紹一些加密過程中用到的原理:
2.1.1對稱加密
? ?對稱加密是指加密和解密使用相同密鑰的加密算法扁藕。它要求發(fā)送方和接收方在安全通信之前,商定一個密鑰疚脐。對稱算法的安全性依賴于密鑰亿柑,泄漏密鑰就意味著任何人都可以對他們發(fā)送或接收的消息解密,所以密鑰的保密性對通信至關(guān)重要棍弄。
對稱加密算法的優(yōu)望薄、缺點:
優(yōu)點:算法公開疟游、計算量小、加密速度快痕支、加密效率高颁虐。
缺點:1)交易雙方都使用同樣鑰匙,安全性得不到保證卧须;
? ? ? ? 2)每對用戶每次使用對稱加密算法時另绩,都需要使用其他人不知道的惟一鑰匙,這會使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級數(shù)增長花嘶,密鑰管理成為用戶的負(fù)擔(dān)笋籽。
? ? ? ? 3)能提供機(jī)密性,但是不能提供驗證和不可否認(rèn)性椭员。
2.1.2非對稱加密算法
這種加密或許理解起來比較困難车海,這種加密指的是可以生成公鑰和私鑰。凡是公鑰加密的數(shù)據(jù)隘击,公鑰自身不能解密侍芝,而需要私鑰才能解密;凡是私鑰加密的數(shù)據(jù)埋同,私鑰不能解密州叠,需要公鑰才能解密。這種算法事實上有很多凶赁,常用的是RSA咧栗,其基于的數(shù)學(xué)原理是兩個大素數(shù)的乘積很容易算,而拿到這個乘積去算出是哪兩個素數(shù)相乘就很復(fù)雜了哟冬,具體原理有興趣可以自行研究。
非對稱加密相比對稱加密更加安全忆绰,但也存在兩個明顯缺點:
? ? ? ?1)CPU計算資源消耗非常大浩峡。一次完全TLS握手,密鑰交換時的非對稱解密計算量占整個握手過程的90%以上错敢。而對稱加密的計算量只相當(dāng)于非對稱加密的0.1%翰灾,如果應(yīng)用層數(shù)據(jù)也使用非對稱加解密,性能開銷太大稚茅,無法承受纸淮。
? ? ? ?2)非對稱加密算法對加密內(nèi)容的長度有限制,不能超過公鑰長度亚享。比如現(xiàn)在常用的公鑰長度是2048位咽块,意味著待加密內(nèi)容不能超過256個字節(jié)。
? ?所以公鑰加密目前只能用來作密鑰交換或者內(nèi)容簽名欺税,不適合用來做應(yīng)用層傳輸內(nèi)容的加解密侈沪。
2.1.3身份認(rèn)證(CA數(shù)字證書)
? ?https協(xié)議中身份認(rèn)證的部分是由數(shù)字證書來完成的揭璃,證書由公鑰、證書主體亭罪、數(shù)字簽名等內(nèi)容組成瘦馍,在客戶端發(fā)起SSL請求后,服務(wù)端會將數(shù)字證書發(fā)給客戶端应役,客戶端會對證書進(jìn)行驗證情组,并獲取用于秘鑰交換的非對稱密鑰。
數(shù)字證書有兩個作用:
1箩祥,身份授權(quán)院崇。確保瀏覽器訪問的網(wǎng)站是經(jīng)過CA驗證的可信任的網(wǎng)站。
2滥比,分發(fā)公鑰亚脆。每個數(shù)字證書都包含了注冊者生成的公鑰。在SSL握手時會通過certificate消息傳輸給客戶端盲泛。
申請一個受信任的數(shù)字證書通常有如下流程:
1濒持,終端實體(可以是一個終端硬件或者網(wǎng)站)生成公私鑰和證書請求。
2寺滚,RA(證書注冊及審核機(jī)構(gòu))檢查實體的合法性柑营。如果個人或者小網(wǎng)站,這一步不是必須的村视。
3官套,CA(證書簽發(fā)機(jī)構(gòu))簽發(fā)證書,發(fā)送給申請者蚁孔。
4奶赔,證書更新到repository(負(fù)責(zé)數(shù)字證書及CRL內(nèi)容存儲和分發(fā)),終端后續(xù)從repository更新證書杠氢,查詢證書狀態(tài)等站刑。
數(shù)字證書驗證:
申請者拿到CA的證書并部署在網(wǎng)站服務(wù)器端,那瀏覽器發(fā)起握手接收到證書后鼻百,如何確認(rèn)這個證書就是CA簽發(fā)的呢绞旅?怎樣避免第三方偽造這個證書?答案就是數(shù)字簽名(digital signature)温艇。數(shù)字簽名是證書的防偽標(biāo)簽因悲,目前使用最廣泛的SHA-RSA(SHA用于哈希算法,RSA用于非對稱加密算法)數(shù)字簽名的制作和驗證過程如下:
1)數(shù)字簽名的簽發(fā)勺爱。首先是使用哈希函數(shù)對待簽名內(nèi)容進(jìn)行安全哈希晃琳,生成消息摘要,然后使用CA自己的私鑰對消息摘要進(jìn)行加密。
2)數(shù)字簽名的校驗蝎土。使用CA的公鑰解密簽名视哑,然后使用相同的簽名函數(shù)對待簽名證書內(nèi)容進(jìn)行簽名并和服務(wù)端數(shù)字簽名里的簽名內(nèi)容進(jìn)行比較,如果相同就認(rèn)為校驗成功誊涯。
需要注意的是:
1)數(shù)字簽名簽發(fā)和校驗使用的密鑰對是CA自己的公私密鑰挡毅,跟證書申請者提交的公鑰沒有關(guān)系。
2)數(shù)字簽名的簽發(fā)過程跟公鑰加密的過程剛好相反暴构,即是用私鑰加密跪呈,公鑰解密。
3)現(xiàn)在大的CA都會有證書鏈取逾,證書鏈的好處一是安全耗绿,保持根CA的私鑰離線使用。第二個好處是方便部署和撤銷砾隅,即如果證書出現(xiàn)問題误阻,只需要撤銷相應(yīng)級別的證書,根證書依然安全晴埂。
4)根CA證書都是自簽名究反,即用自己的公鑰和私鑰完成了簽名的制作和驗證。而證書鏈上的證書簽名都是使用上一級證書的密鑰對完成簽名和驗證的儒洛。
5)怎樣獲取根CA和多級CA的密鑰對精耐?它們是否可信?當(dāng)然可信琅锻,因為這些廠商跟瀏覽器和操作系統(tǒng)都有合作卦停,它們的公鑰都默認(rèn)裝到了瀏覽器或者操作系統(tǒng)環(huán)境里。
2.2加密的詳細(xì)過程
? ?首先服務(wù)器端用非對稱加密(RSA)產(chǎn)生公鑰和私鑰恼蓬。然后把公鑰發(fā)給客 戶端惊完,路徑或許有人會截取,但是沒有用处硬,因為用公鑰加密的文件只有私鑰可以解密小槐,而私鑰永遠(yuǎn)都不會離開服務(wù)器的。當(dāng)公鑰到達(dá)客戶端之后郁油,客戶端會用對稱加密產(chǎn)生一個秘鑰并且用公鑰來加密發(fā)送給服務(wù)器端本股,這個秘鑰就是以后用來通信的鑰匙攀痊。這樣服務(wù)器端收到公鑰加密的秘鑰時就可以用私鑰來解公鑰從而獲得秘鑰桐腌。這樣的話客戶端和服務(wù)器端都獲得了秘鑰,信息交流相對是安全的苟径。流程圖如下:
? ?聽起來確實是挺安全的案站,但實際上,還有一種更惡劣的攻擊是這種方法無 ? 法防范的棘街,這就是傳說中的“中間人攻擊”蟆盐。在身份認(rèn)證的過程中承边,出現(xiàn)了一個“中間人”攔截我們的信息,他有意想要知道你們的消息石挂。我們將這個中間人稱為M博助。當(dāng)服務(wù)器第一次給客戶端發(fā)送公鑰的時候,途徑M痹愚。M知道你要進(jìn)行密鑰交換了富岳,它把公鑰扣了下來,假裝自己是客戶端拯腮,偽造了一個偽秘鑰(對稱加密產(chǎn)生的)窖式,然后用服務(wù)器發(fā)來的公鑰加密了偽秘鑰發(fā)還給服務(wù)器,這樣服務(wù)器以為和客戶端完成了密鑰交換动壤,實際上服務(wù)器是和M完成了密鑰交換(獲得了偽秘鑰)萝喘。同時M假扮成服務(wù)器自行用非對稱加密產(chǎn)生偽公鑰和偽私鑰,與客戶端進(jìn)行秘鑰交換琼懊,拿到客戶端發(fā)送過來的秘鑰「篝ぃ現(xiàn)在客戶端拿著秘鑰,M拿著秘鑰和為偽秘鑰肩碟,服務(wù)器拿著偽秘鑰强窖,整個交流的過程就是:
簡單點說就是:
1)客戶端用秘鑰加密信息發(fā)送給M;
2)M收到后用秘鑰解密拿到信息削祈,然后用偽秘鑰加密信息發(fā)送給服務(wù)器翅溺;
3)服務(wù)器收到后用偽秘鑰解密拿到信息。
這樣中間人M就拿到了客戶端和服務(wù)器所有的交流信息髓抑。
? ?對于這種攻擊咙崎,我們可以加上身份認(rèn)證:這個時候就要引入CA證書,CA證書的原理可回到2.1.3吨拍。數(shù)字證書中包括的主要內(nèi)容有:證書擁有者的個人信息褪猛、證書擁有者的公鑰、公鑰的有效期羹饰、頒發(fā)數(shù)字證書的CA伊滋、CA的數(shù)字簽名等。所以網(wǎng)上雙方經(jīng)過相互驗證數(shù)字證書后队秩,不用再擔(dān)心對方身份的真?zhèn)涡ν梢苑判牡嘏c對方進(jìn)行交流或授予相應(yīng)的資源訪問權(quán)限。
? ?通俗一點理解就是馍资,服務(wù)器端把公鑰交個CA證書筒主,CA證書再包裝一層。(具體原理請回看2.3)然后再發(fā)給客戶端,這個包裝一層的意思是:保證這個證書是我(服務(wù)器)給你(客戶端的)乌妙,其他人拿到了也沒有用使兔。
? ?最后,你可能會想既然非對稱加密可以那么安全藤韵,為什么我們不直接用它來加密信息虐沥,而是用來加密對稱加密的密鑰呢?
? ?這是因為非對稱加密的密碼對生成和加密的消耗時間比較長泽艘,為了節(jié)省雙方的計算時間置蜀,通常只用它來交換密鑰,而非直接用來傳輸數(shù)據(jù)(具體的可看上文非對稱加密的缺點)悉盆。
3.使用AFNetworking進(jìn)行雙向認(rèn)證
3.1客戶端認(rèn)證服務(wù)器端證書
如上圖所示客戶端想要認(rèn)證服務(wù)器盯荤,首先需要和服務(wù)端的數(shù)字證書匹配(server.cer),具體方法如下焕盟。
1)在項目中導(dǎo)入證書sever.cer和AFNetworking框架:
2)然后到AFSecurityPolicy.m中重寫+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode方法:
? ?AFNetworking2是允許內(nèi)嵌證書的秋秤,通過內(nèi)嵌證書,AFNetworking2通過比對服務(wù)器端證書脚翘、內(nèi)嵌的證書灼卢、站點域名是否一致來驗證連接的服務(wù)器是否正確。在完成以上兩條的情況下来农,會自動掃描bundle中.cer的文件鞋真,并引入,這樣就可以通過自簽證書來驗證服務(wù)器唯一性了沃于。
3.2服務(wù)器端認(rèn)證客戶端
1)服務(wù)端驗證客戶端證書涩咖,首先把服務(wù)端的證書client.p12導(dǎo)入到服務(wù)端的密鑰庫里,同時導(dǎo)入工程繁莹;
2)在AFURLConnectionOperation.m中加入以下方法:
3)重寫AFURLConnectionOperation.m中的- (void)connection:(NSURLConnection*)connection
? ?如果是需要認(rèn)證的時候不會先調(diào)用didReceiveResponse檩互,而是先調(diào)用3)和2)的函數(shù),NSURLAuthenticationChallenge是一個認(rèn)證挑戰(zhàn)類咨演,也就是要求客戶端進(jìn)行挑戰(zhàn)闸昨,要接收挑戰(zhàn)也就是客戶端提供挑戰(zhàn)的憑證(用戶和密碼,或者客戶端證書薄风,或者信任服務(wù)器證書饵较,或者代理),IOS提供了一個NSURLCredential的類來表示挑戰(zhàn)憑證遭赂⊙撸可以通過如下函數(shù)來建立挑戰(zhàn)憑證。所以訪問https的時候服務(wù)器認(rèn)證客戶端就調(diào)用這個方法嵌牺。
? ?這兩段代碼是通過p12文件來驗證服務(wù)器的打洼,需要自己修改的地方只有一個,那就是2)中的CFStringRefpassword =CFSTR("123456");這是p12證書的密碼逆粹,用自己的p12證書密碼替換"123456"募疮。
4.3控制器里如何請求
通過4.1和4.2我們的客戶端和服務(wù)器雙向認(rèn)證已經(jīng)設(shè)置好了,在控制器里只需要需要調(diào)用manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];的方法來進(jìn)行雙向認(rèn)證:
然后就可以訪問HTTPS的服務(wù)器了僻弹。