對(duì)于HTTP和TLS,相信很多人都不陌生,特別是開(kāi)發(fā)人員,這應(yīng)該是平時(shí)經(jīng)常接觸的東西。但大伙對(duì)于這塊的知識(shí)可能比較零散,不是很全面,所以小編整理了一下,希望能幫助大伙更好的去鞏固這方面的知識(shí)點(diǎn)。
HTTP和HTTPS
HTTP + 加密 + 認(rèn)證 + 完整性保護(hù) = HTTPS
我們知道HTTP是明文傳輸?shù)模捅夭豢擅獯嬖谌缦聠?wèn)題:
- 重要數(shù)據(jù)被明文獲取
- 通信雙方可能被偽冒
- 數(shù)據(jù)被篡改
- 一般獲取簡(jiǎn)單數(shù)據(jù)用于展示的,可能無(wú)所謂以上的安全缺陷。但假如涉及類(lèi)似銀行密碼的數(shù)據(jù),就必須慎重考慮這一點(diǎn)了。
- 所以能夠規(guī)避以上缺陷的HTTP就是HTTPS(HTTP Secure)。
如何做到加密 + 認(rèn)證 + 完整性保護(hù)
我們都知道OSI7層模型,其中HTTP屬于應(yīng)用層協(xié)議,HTTP下一層是TCP(傳輸層協(xié)議)。完全性是一個(gè)難題,專注于傳輸速率的傳輸層協(xié)議TCP為了單一職責(zé)的理念,自是不會(huì)多管閑事去保證安全性而降低自身的傳輸速率的。
HTTP本身假如要去保證部分?jǐn)?shù)據(jù)的安全性而去專注安全性的開(kāi)發(fā),也是得不償失。想到這里,很是有一些學(xué)JAVA感受到的職責(zé)單一、職責(zé)分離這樣的思想,哈哈。所以應(yīng)該就是這樣,HTTP與TCP之間再加上一層SSL/TLS(Secure Sockets Layer/Transport Layer Security)協(xié)議。

HTTP 請(qǐng)求中的內(nèi)容
HTTP 請(qǐng)求由三部分構(gòu)成,分別為:
- 請(qǐng)求行
- 首部
- 實(shí)體
請(qǐng)求行大概長(zhǎng)這樣 GET /images/logo.gif HTTP/1.1,基本由請(qǐng)求方法、URL、協(xié)議版本組成,這其中值得一說(shuō)的就是請(qǐng)求方法了。
請(qǐng)求方法分為很多種,最常用的也就是 Get 和 Post 了。雖然請(qǐng)求方法有很多,但是更多的是傳達(dá)一個(gè)語(yǔ)義,而不是說(shuō) Post 能做的事情 Get 就不能做了。如果你愿意,都使用 Get 請(qǐng)求或者 Post 請(qǐng)求都是可以的。
問(wèn)題:Post 和 Get 的區(qū)別?
首先先引入副作用和冪等的概念。
副作用指對(duì)服務(wù)器上的資源做改變,搜索是無(wú)副作用的,注冊(cè)是副作用的。
冪等指發(fā)送 M 和 N 次請(qǐng)求(兩者不相同且都大于 1),服務(wù)器上資源的狀態(tài)一致,比如注冊(cè) 10 個(gè)和 11 個(gè)帳號(hào)是不冪等的,對(duì)文章進(jìn)行更改 10 次和 11 次是冪等的。因?yàn)榍罢呤嵌嗔艘粋€(gè)賬號(hào)(資源),后者只是更新同一個(gè)資源。
在規(guī)范的應(yīng)用場(chǎng)景上說(shuō),Get 多用于無(wú)副作用,冪等的場(chǎng)景,例如搜索關(guān)鍵字。Post 多用于副作用,不冪等的場(chǎng)景,例如注冊(cè)。
在技術(shù)上說(shuō):
- Get 請(qǐng)求能緩存,Post 不能
- Post 相對(duì) Get 安全一點(diǎn)點(diǎn),因?yàn)镚et 請(qǐng)求都包含在 URL 里(當(dāng)然你想寫(xiě)到 body 里也是可以的),且會(huì)被瀏覽器保存歷史紀(jì)錄。Post 不會(huì),但是在抓包的情況下都是一樣的。
- URL有長(zhǎng)度限制,會(huì)影響 Get 請(qǐng)求,但是這個(gè)長(zhǎng)度限制是瀏覽器規(guī)定的,不是 RFC 規(guī)定的
- Post 支持更多的編碼類(lèi)型且不對(duì)數(shù)據(jù)類(lèi)型限制
首部
首部分為請(qǐng)求首部和響應(yīng)首部,并且部分首部?jī)煞N通用,接下來(lái)我們就來(lái)學(xué)習(xí)一部分的常用首部。
通用首部

請(qǐng)求首部

響應(yīng)首部

實(shí)體首部

常見(jiàn)狀態(tài)碼
狀態(tài)碼表示了響應(yīng)的一個(gè)狀態(tài),可以讓我們清晰的了解到這一次請(qǐng)求是成功還是失敗,如果失敗的話,是什么原因?qū)е碌模?dāng)然狀態(tài)碼也是用于傳達(dá)語(yǔ)義的。如果胡亂使用狀態(tài)碼,那么它存在的意義就沒(méi)有了。
狀態(tài)碼通常也是面試經(jīng)常會(huì)被考的一道題。
2XX 成功
- 200 OK,表示從客戶端發(fā)來(lái)的請(qǐng)求在服務(wù)器端被正確處理
- 204 No content,表示請(qǐng)求成功,但響應(yīng)報(bào)文不含實(shí)體的主體部分
- 205 Reset Content,表示請(qǐng)求成功,但響應(yīng)報(bào)文不含實(shí)體的主體部分,但是與 204 響應(yīng)不同在于要求請(qǐng)求方重置內(nèi)容
- 206 Partial Content,進(jìn)行范圍請(qǐng)求
3XX 重定向
- 301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
- 302 found,臨時(shí)性重定向,表示資源臨時(shí)被分配了新的 URL
- 303 see other,表示資源存在著另一個(gè) URL,應(yīng)使用 GET 方法獲取資源
- 304 not modified,表示服務(wù)器允許訪問(wèn)資源,但因發(fā)生請(qǐng)求未滿足條件的情況
- 307 temporary redirect,臨時(shí)重定向,和302含義類(lèi)似,但是期望客戶端保持請(qǐng)求方法不變向新的地址發(fā)出請(qǐng)求
4XX 客戶端錯(cuò)誤
- 400 bad request,請(qǐng)求報(bào)文存在語(yǔ)法錯(cuò)誤
- 401 unauthorized,表示發(fā)送的請(qǐng)求需要有通過(guò) HTTP 認(rèn)證的認(rèn)證信息
- 403 forbidden,表示對(duì)請(qǐng)求資源的訪問(wèn)被服務(wù)器拒絕
- 404 not found,表示在服務(wù)器上沒(méi)有找到請(qǐng)求的資源
5XX 服務(wù)器錯(cuò)誤
- 500 internal sever error,表示服務(wù)器端在執(zhí)行請(qǐng)求時(shí)發(fā)生了錯(cuò)誤
- 501 Not Implemented,表示服務(wù)器不支持當(dāng)前請(qǐng)求所需要的某個(gè)功能
- 503 service unavailable,表明服務(wù)器暫時(shí)處于超負(fù)載或正在停機(jī)維護(hù),無(wú)法處理請(qǐng)求
TLS協(xié)議
HTTPS 還是通過(guò)了 HTTP 來(lái)傳輸信息,但是信息通過(guò) TLS 協(xié)議進(jìn)行了加密。
TLS 協(xié)議位于傳輸層之上,應(yīng)用層之下。首次進(jìn)行 TLS 協(xié)議傳輸需要兩個(gè) RTT ,接下來(lái)可以通過(guò) Session Resumption 減少到一個(gè) RTT。
在 TLS 中使用了兩種加密技術(shù),分別為:對(duì)稱加密和非對(duì)稱加密。
對(duì)稱加密:
對(duì)稱加密就是兩邊擁有相同的秘鑰,兩邊都知道如何將密文加密解密。
這種加密方式固然很好,但是問(wèn)題就在于如何讓雙方知道秘鑰。因?yàn)閭鬏敂?shù)據(jù)都是走的網(wǎng)絡(luò),如果將秘鑰通過(guò)網(wǎng)絡(luò)的方式傳遞的話,一旦秘鑰被截獲就沒(méi)有加密的意義的。
非對(duì)稱加密:
有公鑰私鑰之分,公鑰所有人都可以知道,可以將數(shù)據(jù)用公鑰加密,但是將數(shù)據(jù)解密必須使用私鑰解密,私鑰只有分發(fā)公鑰的一方才知道。
這種加密方式就可以完美解決對(duì)稱加密存在的問(wèn)題。假設(shè)現(xiàn)在兩端需要使用對(duì)稱加密,那么在這之前,可以先使用非對(duì)稱加密交換秘鑰。
簡(jiǎn)單流程如下:首先服務(wù)端將公鑰公布出去,那么客戶端也就知道公鑰了。接下來(lái)客戶端創(chuàng)建一個(gè)秘鑰,然后通過(guò)公鑰加密并發(fā)送給服務(wù)端,服務(wù)端接收到密文以后通過(guò)私鑰解密出正確的秘鑰,這時(shí)候兩端就都知道秘鑰是什么了。
TLS 握手過(guò)程如下圖:

客戶端發(fā)送一個(gè)隨機(jī)值以及需要的協(xié)議和加密方式。
服務(wù)端收到客戶端的隨機(jī)值,自己也產(chǎn)生一個(gè)隨機(jī)值,并根據(jù)客戶端需求的協(xié)議和加密方式來(lái)使用對(duì)應(yīng)的方式,并且發(fā)送自己的證書(shū)(如果需要驗(yàn)證客戶端證書(shū)需要說(shuō)明)
客戶端收到服務(wù)端的證書(shū)并驗(yàn)證是否有效,驗(yàn)證通過(guò)會(huì)再生成一個(gè)隨機(jī)值,通過(guò)服務(wù)端證書(shū)的公鑰去加密這個(gè)隨機(jī)值并發(fā)送給服務(wù)端,如果服務(wù)端需要驗(yàn)證客戶端證書(shū)的話會(huì)附帶證書(shū)
服務(wù)端收到加密過(guò)的隨機(jī)值并使用私鑰解密獲得第三個(gè)隨機(jī)值,這時(shí)候兩端都擁有了三個(gè)隨機(jī)值,可以通過(guò)這三個(gè)隨機(jī)值按照之前約定的加密方式生成密鑰,接下來(lái)的通信就可以通過(guò)該密鑰來(lái)加密解密
通過(guò)以上步驟可知,在 TLS 握手階段,兩端使用非對(duì)稱加密的方式來(lái)通信,但是因?yàn)榉菍?duì)稱加密損耗的性能比對(duì)稱加密大,所以在正式傳輸數(shù)據(jù)時(shí),兩端使用對(duì)稱加密的方式通信。
備注:以上說(shuō)明的都是 TLS 1.2 協(xié)議的握手情況,在 1.3 協(xié)議中,首次建立連接只需要一個(gè) RTT,后面恢復(fù)連接不需要 RTT 了。
小結(jié)
這篇文章的內(nèi)容還是相對(duì)比較多的,需要同學(xué)們多次閱讀,慢慢理解,里面有些術(shù)語(yǔ)如果不太懂的同學(xué)可以去網(wǎng)上學(xué)習(xí)一下,下面總結(jié)一下內(nèi)容:
- 介紹了HTTP、HTTPS和TSL之間的關(guān)系
- 詳細(xì)介紹HTTP的請(qǐng)求內(nèi)容和狀態(tài)碼
- 介紹TLS 中經(jīng)常用到的兩種加密方式以及握手的流程