今天工作的時(shí)候在配置https,一時(shí)興起,簡(jiǎn)單記錄一下自己對(duì)https的理解,以及如何在web中使用,我們主要討論幾個(gè)問題
- 為什么要用https
- https是如何建立鏈接的
- 實(shí)際使用中的問題
1. 為什么要用https而不是http
- 通信使用明文( 不加密) , 內(nèi)容可能會(huì)被竊聽
- 不驗(yàn)證通信方的身份, 因此有可能遭遇偽裝
- 無法證明報(bào)文的完整性, 所以有可能已遭篡改這些問題不僅在 HTTP 上出現(xiàn),其他未加密的協(xié)議中也會(huì)存在這類問題。
2. 如何解決http協(xié)議中的安全問題
我們需要采用SSL, SSL不僅提供加密處理,而且還使用了一種被稱為證書的手段,可用于確定方。證書由值得信任的第三方機(jī)構(gòu)頒發(fā),用以證明服務(wù)器和客戶端是實(shí)際存在的。另外,偽造證書從技術(shù)角度來說是異常困難的一件事。所以只要能夠確認(rèn)通信方(服務(wù)器或客戶端)持有的證書,即可判斷通信方的真實(shí)意圖
我們可以簡(jiǎn)單理解為 https 就是 http 套上了 ssl 的外殼 (?????)? ??
3. 拋開上面的概念問題,我們自己考慮下如何保證通訊的安全 (? ??_??)?
- 對(duì)稱加密是否可行?
- 該方式加解密的密鑰是同一個(gè),對(duì)稱加密的安全度很高
- 假設(shè) A 和 B 通信,A 發(fā)出的消息經(jīng)過密鑰加密發(fā)送,B 收到消息后,用密鑰解密
- 在保證密鑰不泄露的情況下,這種方式是絕對(duì)OK的
- 但是在網(wǎng)絡(luò)中的情況很復(fù)雜,要實(shí)現(xiàn)對(duì)稱加密,需要客戶端和服務(wù)端同時(shí)具備密鑰,在密鑰的保存和傳遞過程中,很容易出現(xiàn)泄露,尤其是在客戶端
- 所以對(duì)稱加密一定可行,但是不能直接采用,我們還需要改進(jìn)!(? ??_??)?
- 如何在對(duì)稱加密的基礎(chǔ)上改進(jìn)?
- 密鑰應(yīng)該是在每次發(fā)起請(qǐng)求時(shí)臨時(shí)生成的,如果是一個(gè)固定的密鑰,就始終存在著泄露的風(fēng)險(xiǎn),SSL就采用的協(xié)商機(jī)制來解決這個(gè)問題
- 我們需要保證對(duì)稱加密的密鑰在傳遞過程中的安全,這里我們就需要借助非對(duì)稱加密(公鑰 私鑰)
- 非對(duì)稱加密的作用?
- 非對(duì)稱加密的密鑰分為
公鑰
和私鑰
, (公鑰加密,私鑰解密),(私鑰加密,公鑰解密) - https中,這種加密方式主要是為了規(guī)避對(duì)稱加密在密鑰傳遞過程中的安全問題
- 公鑰是公開的,誰(shuí)都可以拿到,私鑰只有服務(wù)器擁有,不會(huì)傳遞,所以不用擔(dān)心泄露
- 由于公鑰是公開的,所以服務(wù)器加密的數(shù)據(jù),任何持有公鑰的客戶端都可以解密,所以服務(wù)器 -> 瀏覽器的信息,約等于明文,不具備安全性
- 由于私鑰服務(wù)器擁有,不傳遞,任何以公鑰加密的數(shù)據(jù),只有服務(wù)器可以解開,所以瀏覽器 -> 服務(wù)器的信息發(fā)送,是安全的
- 非對(duì)稱加密具有單向安全性
- 所以我們可以利用這個(gè)特點(diǎn),如果對(duì)稱加密的密鑰由客戶端(瀏覽器)生成,再用公鑰加密發(fā)送給服務(wù)器,服務(wù)器得到對(duì)稱密鑰后,雙方再以對(duì)稱加密的方式通信,就可以保證通信的安全
- 非對(duì)稱加密的密鑰分為
- 服務(wù)器和客戶端如何協(xié)商生成對(duì)稱密鑰?
- 我們已經(jīng)提到,需要讓對(duì)稱密鑰臨時(shí)生成,這里我們引入一種協(xié)商機(jī)制(
后面再討論公鑰篡改問題,先忽略
) - 建立https鏈接的時(shí)候,瀏覽器會(huì)先向服務(wù)器發(fā)送自己支持的
加密算法
和摘要算法
,并且附帶一個(gè)隨機(jī)數(shù)
- 服務(wù)器收到請(qǐng)求后,返回公鑰,同時(shí)也附帶一個(gè)
隨機(jī)數(shù)
- 瀏覽器收到公鑰后,再次生成隨機(jī)數(shù),利用剛才這3個(gè)隨機(jī)數(shù)生成一個(gè)對(duì)稱密鑰,公鑰加密該對(duì)稱密鑰,發(fā)送給服務(wù)器,之后就可以開始對(duì)稱加密通信了(? ??_??)?
- 每次請(qǐng)求都會(huì)重復(fù)以上步驟
- 我們已經(jīng)提到,需要讓對(duì)稱密鑰臨時(shí)生成,這里我們引入一種協(xié)商機(jī)制(
以上就是https建立鏈接的大體步驟(當(dāng)然,我們忽略了公鑰篡改問題)
4. 如何確保公鑰沒有被篡改
由于非對(duì)稱加密只具有單向安全性,公鑰的傳遞,必定是不安全的,以上的https鏈接創(chuàng)建,是我們假設(shè)得到了正確的公鑰,由于公鑰是公開的,所以公鑰本身,有被篡改的可能,那么我們?nèi)绾谓鉀Q這個(gè)問題呢
這里要涉及兩個(gè)非常重要的概念:
證書
、CA(證書頒發(fā)機(jī)構(gòu))
- "證書",可以暫時(shí)把它理解為網(wǎng)站的身份證。這個(gè)身份證里包含了很多信息,其中就包含了上面提到的公鑰。
- 也就是說,等用戶通過瀏覽器訪問服務(wù)器的時(shí)候,再也不用滿世界的找某個(gè)服務(wù)器的公鑰了。當(dāng)他們?cè)L問某服務(wù)器的時(shí)候,這臺(tái)服務(wù)器就會(huì)把證書發(fā)給瀏覽器,告訴他們說,乖,用這個(gè)里面的公鑰加密數(shù)據(jù)。
這里有個(gè)問題,所謂的“證書”是哪來的?這就是下面要提到的CA負(fù)責(zé)的活了。
- CA(證書頒發(fā)機(jī)構(gòu)),可以頒發(fā)證書的CA有很多(國(guó)內(nèi)外都有),但是只有少數(shù)CA被認(rèn)為是權(quán)威、公正的,這些CA頒發(fā)的證書,瀏覽器才認(rèn)為是信得過的,我們的操作系統(tǒng)中會(huì)預(yù)先安裝好一些證書發(fā)布機(jī)構(gòu)的證書。比如VeriSign。(CA自己偽造證書的事情也不是沒發(fā)生過。。。)證書頒發(fā)的細(xì)節(jié)這里先不展開,可以先簡(jiǎn)單理解為,網(wǎng)站向CA提交了申請(qǐng),CA審核通過后,將證書頒發(fā)給網(wǎng)站,用戶訪問網(wǎng)站的時(shí)候,網(wǎng)站將證書給到用戶。
證書可以證明當(dāng)前傳遞的公鑰是合法有效的,但是CA證書也是服務(wù)器傳遞的,CA證書里面的公鑰還是有被篡改的問題,這里會(huì)涉及到
簽名
和根證書
- 根證書:CA機(jī)構(gòu)自己也有一個(gè)證書,就叫做根證書,并且CA機(jī)構(gòu)有自己的私鑰和公鑰,CA機(jī)構(gòu)頒發(fā)的證書,都用CA機(jī)構(gòu)的私鑰加密過
- 簽名:就是對(duì)傳輸?shù)膬?nèi)容,通過hash算法計(jì)算出一段固定長(zhǎng)度的串,通過CA機(jī)構(gòu)的私鑰對(duì)這段摘要進(jìn)行加密,加密后得到的結(jié)果就是“數(shù)字簽名”。數(shù)字簽名只能驗(yàn)證數(shù)據(jù)的完整性,數(shù)據(jù)本身是否加密不屬于數(shù)字簽名的控制范圍
- 我們的瀏覽器中,內(nèi)置了大多數(shù)權(quán)威CA機(jī)構(gòu)的根證書,當(dāng)我們收到一個(gè)CA證書的時(shí)候,瀏覽器會(huì)找到相應(yīng)CA機(jī)構(gòu)的根證書,取出公鑰,對(duì)CA證書解密,并比對(duì)數(shù)字簽名
以上方式就保證了證書本身的安全性
5. 總結(jié)一下https完整的建立連接步驟
TCP三次握手
Client Hello – 客戶端發(fā)送所支持的 SSL/TLS 最高協(xié)議版本號(hào)、所支持的
加密算法
及壓縮方法
和隨機(jī)數(shù)A
等信息給服務(wù)器端。Server Hello – 服務(wù)器端收到客戶端信息后,選定雙方都能夠支持的
SSL/TLS 協(xié)議版本
和加密方法
及壓縮方法
、隨機(jī)數(shù)B
和服務(wù)器證書
返回給客戶端。客戶端根據(jù)證書類型,找到內(nèi)置的根證書,對(duì)證書進(jìn)行解密,并驗(yàn)證
數(shù)字簽名
有效性,如果是非法證書,拒絕連接,并在頁(yè)面提醒,如果你選擇信任該證書,依然可以繼續(xù)客戶端主動(dòng)再生成一個(gè)
隨機(jī)數(shù)C
,開始生成秘鑰,這個(gè)生成秘鑰的算法是客戶端跟服務(wù)器端共享的,因?yàn)橹皡f(xié)商的時(shí)候已經(jīng)確定了算法了,生成秘鑰后就可以加密一段內(nèi)容,試著跟服務(wù)區(qū)通信了,這個(gè)內(nèi)容是經(jīng)過先散列,散列后將原內(nèi)容和散列集一起用剛才的密鑰加密;接著用服務(wù)器端證書中的公鑰對(duì)隨機(jī)數(shù)C加密。然后把加密過的內(nèi)容和加密好的隨機(jī)數(shù)一起發(fā)向服務(wù)器端。
服務(wù)器用私鑰解密得到隨機(jī)數(shù)C,這樣服務(wù)器端也同時(shí)擁有了隨機(jī)數(shù)A、B、C,即刻生成密鑰,再用密鑰對(duì)加密的內(nèi)容進(jìn)行解密,然后解開后對(duì)其中的明文內(nèi)容進(jìn)行散列,與客戶端發(fā)過來的散列值進(jìn)行比較,如果相等,說明就是客戶端發(fā)過來的,通信成功。
用步驟3中同樣的方式發(fā)一段加密過的內(nèi)容給客戶端。
用步驟5一樣的方式對(duì)服務(wù)器發(fā)來的內(nèi)容進(jìn)行驗(yàn)證。
客戶端確定開始通信。
服務(wù)端確定開始通信。
6. https使用中的問題
-
只有注冊(cè)登錄頁(yè),才需要HTTPS?
- 當(dāng)然不是,如果僅在登錄頁(yè)使用了HTTPS,但是登錄以后,其他頁(yè)面就變成了HTTP。這時(shí),我們的cookie里的session值就暴露了。
-
HTTPS太慢?
- 這個(gè)在工作中試過,由于一直都在用Https,和http相比,使用上沒有速度快慢的感覺,https建立連接的開銷,對(duì)于目前的硬件性能,不值一提
-
免費(fèi)的證書哪里搞?
- https://www.startcomca.com/ 好東西,不多說