對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)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議砖瞧,比http協(xié)議安全息堂。
1.2http為什么不安全
http協(xié)議沒有任何的加密以及身份驗證的機制,非常容易遭遇竊聽芭届、劫持、篡改感耙,因此會造成個人隱私泄露褂乍,惡意的流量劫持等嚴重的安全問題。
就像寄信一樣即硼,我給你寄信逃片,中間可能會經(jīng)過很多的郵遞員,他們可以拆開信讀取里面的內(nèi)容,因為是明文的褥实。如果你的信里涉及到了你們銀行賬號等敏感信息呀狼,可能就會被竊取。除此之外损离,郵遞員們還可以給你偽造信的內(nèi)容哥艇,導(dǎo)致你遭到欺騙。
1.3https如何保證安全
HTTPS是以安全為目標的HTTP通道僻澎,簡單講是HTTP的安全版貌踏。即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL窟勃,因此加密的詳細內(nèi)容就需要SSL祖乳。它是一個URI scheme(抽象標識符體系),句法類同http:體系秉氧。用于安全的HTTP數(shù)據(jù)傳輸眷昆。https:URL表明它使用了HTTPS,但HTTPS存在不同于HTTP的默認端口及一個加密/身份驗證層(在HTTP與TCP之間)汁咏。這個系統(tǒng)的最初研發(fā)由網(wǎng)景公司進行亚斋,提供了身份驗證與加密通訊方法,現(xiàn)在它被廣泛用于萬維網(wǎng)上安全敏感的通訊梆暖,例如交易支付方面伞访。
2.HTTPS的加密原理
2.1首先先介紹一些加密過程中用到的原理:
2.1.1對稱加密
對稱加密是指加密和解密使用相同密鑰的加密算法。它要求發(fā)送方和接收方在安全通信之前轰驳,商定一個密鑰梯找。對稱算法的安全性依賴于密鑰,泄漏密鑰就意味著任何人都可以對他們發(fā)送或接收的消息解密办绝,所以密鑰的保密性對通信至關(guān)重要试伙。
對稱加密算法的優(yōu)、缺點:
優(yōu)點:算法公開勤哗、計算量小抡爹、加密速度快、加密效率高芒划。
缺點:1)交易雙方都使用同樣鑰匙冬竟,安全性得不到保證;
2)每對用戶每次使用對稱加密算法時民逼,都需要使用其他人不知道的惟一鑰匙泵殴,這會使得發(fā)收信雙方所擁有的鑰匙數(shù)量呈幾何級數(shù)增長,密鑰管理成為用戶的負擔(dān)拼苍。
3)能提供機密性笑诅,但是不能提供驗證和不可否認性。
2.1.2非對稱加密算法
這種加密或許理解起來比較困難,這種加密指的是可以生成公鑰和私鑰吆你。凡是公鑰加密的數(shù)據(jù)弦叶,公鑰自身不能解密,而需要私鑰才能解密妇多;凡是私鑰加密的數(shù)據(jù)伤哺,私鑰不能解密,需要公鑰才能解密砌梆。這種算法事實上有很多默责,常用的是RSA,其基于的數(shù)學(xué)原理是兩個大素數(shù)的乘積很容易算咸包,而拿到這個乘積去算出是哪兩個素數(shù)相乘就很復(fù)雜了桃序,具體原理有興趣可以自行研究。
非對稱加密相比對稱加密更加安全烂瘫,但也存在兩個明顯缺點:
1)CPU計算資源消耗非常大媒熊。一次完全TLS握手,密鑰交換時的非對稱解密計算量占整個握手過程的90%以上坟比。而對稱加密的計算量只相當于非對稱加密的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身份認證(CA數(shù)字證書)
https協(xié)議中身份認證的部分是由數(shù)字證書來完成的,證書由公鑰呜达、證書主體谣蠢、數(shù)字簽名等內(nèi)容組成,在客戶端發(fā)起SSL請求后查近,服務(wù)端會將數(shù)字證書發(fā)給客戶端眉踱,客戶端會對證書進行驗證,并獲取用于秘鑰交換的非對稱密鑰霜威。
數(shù)字證書有兩個作用:
1谈喳,身份授權(quán)。確保瀏覽器訪問的網(wǎng)站是經(jīng)過CA驗證的可信任的網(wǎng)站侥祭。
2叁执,分發(fā)公鑰。每個數(shù)字證書都包含了注冊者生成的公鑰矮冬。在SSL握手時會通過certificate消息傳輸給客戶端谈宛。
申請一個受信任的數(shù)字證書通常有如下流程:
1,終端實體(可以是一個終端硬件或者網(wǎng)站)生成公私鑰和證書請求胎署。
2吆录,RA(證書注冊及審核機構(gòu))檢查實體的合法性。如果個人或者小網(wǎng)站琼牧,這一步不是必須的恢筝。
3,CA(證書簽發(fā)機構(gòu))簽發(fā)證書巨坊,發(fā)送給申請者撬槽。
4,證書更新到repository(負責(zé)數(shù)字證書及CRL內(nèi)容存儲和分發(fā))趾撵,終端后續(xù)從repository更新證書侄柔,查詢證書狀態(tài)等。
數(shù)字證書驗證:
申請者拿到CA的證書并部署在網(wǎng)站服務(wù)器端占调,那瀏覽器發(fā)起握手接收到證書后暂题,如何確認這個證書就是CA簽發(fā)的呢?怎樣避免第三方偽造這個證書究珊?答案就是數(shù)字簽名(digital signature)薪者。數(shù)字簽名是證書的防偽標簽,目前使用最廣泛的SHA-RSA(SHA用于哈希算法剿涮,RSA用于非對稱加密算法)數(shù)字簽名的制作和驗證過程如下:
1)數(shù)字簽名的簽發(fā)言津。首先是使用哈希函數(shù)對待簽名內(nèi)容進行安全哈希,生成消息摘要幔虏,然后使用CA自己的私鑰對消息摘要進行加密纺念。
2)數(shù)字簽名的校驗。使用CA的公鑰解密簽名想括,然后使用相同的簽名函數(shù)對待簽名證書內(nèi)容進行簽名并和服務(wù)端數(shù)字簽名里的簽名內(nèi)容進行比較陷谱,如果相同就認為校驗成功。
需要注意的是:
1)數(shù)字簽名簽發(fā)和校驗使用的密鑰對是CA自己的公私密鑰瑟蜈,跟證書申請者提交的公鑰沒有關(guān)系烟逊。
2)數(shù)字簽名的簽發(fā)過程跟公鑰加密的過程剛好相反,即是用私鑰加密铺根,公鑰解密宪躯。
3)現(xiàn)在大的CA都會有證書鏈,證書鏈的好處一是安全位迂,保持根CA的私鑰離線使用访雪。第二個好處是方便部署和撤銷详瑞,即如果證書出現(xiàn)問題,只需要撤銷相應(yīng)級別的證書臣缀,根證書依然安全坝橡。
4)根CA證書都是自簽名,即用自己的公鑰和私鑰完成了簽名的制作和驗證精置。而證書鏈上的證書簽名都是使用上一級證書的密鑰對完成簽名和驗證的计寇。
5)怎樣獲取根CA和多級CA的密鑰對?它們是否可信脂倦?當然可信番宁,因為這些廠商跟瀏覽器和操作系統(tǒng)都有合作,它們的公鑰都默認裝到了瀏覽器或者操作系統(tǒng)環(huán)境里赖阻。
2.2加密的詳細過程
首先服務(wù)器端用非對稱加密(RSA)產(chǎn)生公鑰和私鑰蝶押。然后把公鑰發(fā)給客 戶端,路徑或許有人會截取火欧,但是沒有用播聪,因為用公鑰加密的文件只有私鑰可以解密,而私鑰永遠都不會離開服務(wù)器的布隔。當公鑰到達客戶端之后离陶,客戶端會用對稱加密產(chǎn)生一個秘鑰并且用公鑰來加密發(fā)送給服務(wù)器端,這個秘鑰就是以后用來通信的鑰匙衅檀。這樣服務(wù)器端收到公鑰加密的秘鑰時就可以用私鑰來解公鑰從而獲得秘鑰招刨。這樣的話客戶端和服務(wù)器端都獲得了秘鑰,信息交流相對是安全的哀军。流程圖如下:
聽起來確實是挺安全的沉眶,但實際上,還有一種更惡劣的攻擊是這種方法無? 法防范的杉适,這就是傳說中的“中間人攻擊”谎倔。在身份認證的過程中,出現(xiàn)了一個“中間人”攔截我們的信息猿推,他有意想要知道你們的消息片习。我們將這個中間人稱為M。當服務(wù)器第一次給客戶端發(fā)送公鑰的時候蹬叭,途徑M藕咏。M知道你要進行密鑰交換了,它把公鑰扣了下來秽五,假裝自己是客戶端孽查,偽造了一個偽秘鑰(對稱加密產(chǎn)生的),然后用服務(wù)器發(fā)來的公鑰加密了偽秘鑰發(fā)還給服務(wù)器坦喘,這樣服務(wù)器以為和客戶端完成了密鑰交換盲再,實際上服務(wù)器是和M完成了密鑰交換(獲得了偽秘鑰)西设。同時M假扮成服務(wù)器自行用非對稱加密產(chǎn)生偽公鑰和偽私鑰,與客戶端進行秘鑰交換答朋,拿到客戶端發(fā)送過來的秘鑰〖谜ィ現(xiàn)在客戶端拿著秘鑰,M拿著秘鑰和為偽秘鑰绿映,服務(wù)器拿著偽秘鑰,整個交流的過程就是:
簡單點說就是:
1)客戶端用秘鑰加密信息發(fā)送給M腐晾;
2)M收到后用秘鑰解密拿到信息叉弦,然后用偽秘鑰加密信息發(fā)送給服務(wù)器;
3)服務(wù)器收到后用偽秘鑰解密拿到信息藻糖。
這樣中間人M就拿到了客戶端和服務(wù)器所有的交流信息淹冰。
對于這種攻擊,我們可以加上身份認證:這個時候就要引入CA證書巨柒,CA證書的原理可回到2.1.3樱拴。數(shù)字證書中包括的主要內(nèi)容有:證書擁有者的個人信息、證書擁有者的公鑰洋满、公鑰的有效期晶乔、頒發(fā)數(shù)字證書的CA、CA的數(shù)字簽名等牺勾。所以網(wǎng)上雙方經(jīng)過相互驗證數(shù)字證書后正罢,不用再擔(dān)心對方身份的真?zhèn)危梢苑判牡嘏c對方進行交流或授予相應(yīng)的資源訪問權(quán)限驻民。
通俗一點理解就是翻具,服務(wù)器端把公鑰交個CA證書,CA證書再包裝一層回还。(具體原理請回看2.3)然后再發(fā)給客戶端裆泳,這個包裝一層的意思是:保證這個證書是我(服務(wù)器)給你(客戶端的),其他人拿到了也沒有用柠硕。
最后工禾,你可能會想既然非對稱加密可以那么安全,為什么我們不直接用它來加密信息蝗柔,而是用來加密對稱加密的密鑰呢帜篇?
這是因為非對稱加密的密碼對生成和加密的消耗時間比較長,為了節(jié)省雙方的計算時間诫咱,通常只用它來交換密鑰笙隙,而非直接用來傳輸數(shù)據(jù)(具體的可看上文非對稱加密的缺點)。
3.使用AFNetworking進行雙向認證
3.1客戶端認證服務(wù)器端證書
如上圖所示客戶端想要認證服務(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ù)器端認證客戶端
1)服務(wù)端驗證客戶端證書,首先把服務(wù)端的證書client.p12導(dǎo)入到服務(wù)端的密鑰庫里级及,同時導(dǎo)入工程乒疏;
2)在AFURLConnectionOperation.m中加入以下方法:
3)重寫AFURLConnectionOperation.m中的- (void)connection:(NSURLConnection*)connection
如果是需要認證的時候不會先調(diào)用didReceiveResponse,而是先調(diào)用3)和2)的函數(shù)饮焦,NSURLAuthenticationChallenge是一個認證挑戰(zhàn)類怕吴,也就是要求客戶端進行挑戰(zhàn),要接收挑戰(zhàn)也就是客戶端提供挑戰(zhàn)的憑證(用戶和密碼县踢,或者客戶端證書转绷,或者信任服務(wù)器證書,或者代理)硼啤,IOS提供了一個NSURLCredential的類來表示挑戰(zhàn)憑證暇咆。可以通過如下函數(shù)來建立挑戰(zhàn)憑證丙曙。所以訪問https的時候服務(wù)器認證客戶端就調(diào)用這個方法爸业。
這兩段代碼是通過p12文件來驗證服務(wù)器的,需要自己修改的地方只有一個亏镰,那就是2)中的CFStringRefpassword =CFSTR("123456");這是p12證書的密碼扯旷,用自己的p12證書密碼替換"123456"。
4.3控制器里如何請求
通過4.1和4.2我們的客戶端和服務(wù)器雙向認證已經(jīng)設(shè)置好了索抓,在控制器里只需要需要調(diào)用manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];的方法來進行雙向認證:
然后就可以訪問HTTPS的服務(wù)器了钧忽。