對于HTTP和TLS,相信很多人都不陌生,特別是開發(fā)人員,這應該是平時經(jīng)常接觸的東西。但大伙對于這塊的知識可能比較零散,不是很全面,所以小編整理了一下,希望能幫助大伙更好的去鞏固這方面的知識點。
HTTP和HTTPS
HTTP + 加密 + 認證 + 完整性保護 = HTTPS
我們知道HTTP是明文傳輸?shù)模捅夭豢擅獯嬖谌缦聠栴}:
- 重要數(shù)據(jù)被明文獲取
- 通信雙方可能被偽冒
- 數(shù)據(jù)被篡改
- 一般獲取簡單數(shù)據(jù)用于展示的,可能無所謂以上的安全缺陷。但假如涉及類似銀行密碼的數(shù)據(jù),就必須慎重考慮這一點了。
- 所以能夠規(guī)避以上缺陷的HTTP就是HTTPS(HTTP Secure)。
如何做到加密 + 認證 + 完整性保護
我們都知道OSI7層模型,其中HTTP屬于應用層協(xié)議,HTTP下一層是TCP(傳輸層協(xié)議)。完全性是一個難題,專注于傳輸速率的傳輸層協(xié)議TCP為了單一職責的理念,自是不會多管閑事去保證安全性而降低自身的傳輸速率的。
HTTP本身假如要去保證部分數(shù)據(jù)的安全性而去專注安全性的開發(fā),也是得不償失。想到這里,很是有一些學JAVA感受到的職責單一、職責分離這樣的思想,哈哈。所以應該就是這樣,HTTP與TCP之間再加上一層SSL/TLS(Secure Sockets Layer/Transport Layer Security)協(xié)議。
HTTP 請求中的內(nèi)容
HTTP 請求由三部分構成,分別為:
- 請求行
- 首部
- 實體
請求行大概長這樣 GET /images/logo.gif HTTP/1.1,基本由請求方法、URL、協(xié)議版本組成,這其中值得一說的就是請求方法了。
請求方法分為很多種,最常用的也就是 Get 和 Post 了。雖然請求方法有很多,但是更多的是傳達一個語義,而不是說 Post 能做的事情 Get 就不能做了。如果你愿意,都使用 Get 請求或者 Post 請求都是可以的。
問題:Post 和 Get 的區(qū)別?
首先先引入副作用和冪等的概念。
副作用指對服務器上的資源做改變,搜索是無副作用的,注冊是副作用的。
冪等指發(fā)送 M 和 N 次請求(兩者不相同且都大于 1),服務器上資源的狀態(tài)一致,比如注冊 10 個和 11 個帳號是不冪等的,對文章進行更改 10 次和 11 次是冪等的。因為前者是多了一個賬號(資源),后者只是更新同一個資源。
在規(guī)范的應用場景上說,Get 多用于無副作用,冪等的場景,例如搜索關鍵字。Post 多用于副作用,不冪等的場景,例如注冊。
在技術上說:
- Get 請求能緩存,Post 不能
- Post 相對 Get 安全一點點,因為Get 請求都包含在 URL 里(當然你想寫到 body 里也是可以的),且會被瀏覽器保存歷史紀錄。Post 不會,但是在抓包的情況下都是一樣的。
- URL有長度限制,會影響 Get 請求,但是這個長度限制是瀏覽器規(guī)定的,不是 RFC 規(guī)定的
- Post 支持更多的編碼類型且不對數(shù)據(jù)類型限制
首部
首部分為請求首部和響應首部,并且部分首部兩種通用,接下來我們就來學習一部分的常用首部。
通用首部
請求首部
響應首部
實體首部
常見狀態(tài)碼
狀態(tài)碼表示了響應的一個狀態(tài),可以讓我們清晰的了解到這一次請求是成功還是失敗,如果失敗的話,是什么原因?qū)е碌模斎粻顟B(tài)碼也是用于傳達語義的。如果胡亂使用狀態(tài)碼,那么它存在的意義就沒有了。
狀態(tài)碼通常也是面試經(jīng)常會被考的一道題。
2XX 成功
- 200 OK,表示從客戶端發(fā)來的請求在服務器端被正確處理
- 204 No content,表示請求成功,但響應報文不含實體的主體部分
- 205 Reset Content,表示請求成功,但響應報文不含實體的主體部分,但是與 204 響應不同在于要求請求方重置內(nèi)容
- 206 Partial Content,進行范圍請求
3XX 重定向
- 301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
- 302 found,臨時性重定向,表示資源臨時被分配了新的 URL
- 303 see other,表示資源存在著另一個 URL,應使用 GET 方法獲取資源
- 304 not modified,表示服務器允許訪問資源,但因發(fā)生請求未滿足條件的情況
- 307 temporary redirect,臨時重定向,和302含義類似,但是期望客戶端保持請求方法不變向新的地址發(fā)出請求
4XX 客戶端錯誤
- 400 bad request,請求報文存在語法錯誤
- 401 unauthorized,表示發(fā)送的請求需要有通過 HTTP 認證的認證信息
- 403 forbidden,表示對請求資源的訪問被服務器拒絕
- 404 not found,表示在服務器上沒有找到請求的資源
5XX 服務器錯誤
- 500 internal sever error,表示服務器端在執(zhí)行請求時發(fā)生了錯誤
- 501 Not Implemented,表示服務器不支持當前請求所需要的某個功能
- 503 service unavailable,表明服務器暫時處于超負載或正在停機維護,無法處理請求
TLS協(xié)議
HTTPS 還是通過了 HTTP 來傳輸信息,但是信息通過 TLS 協(xié)議進行了加密。
TLS 協(xié)議位于傳輸層之上,應用層之下。首次進行 TLS 協(xié)議傳輸需要兩個 RTT ,接下來可以通過 Session Resumption 減少到一個 RTT。
在 TLS 中使用了兩種加密技術,分別為:對稱加密和非對稱加密。
對稱加密:
對稱加密就是兩邊擁有相同的秘鑰,兩邊都知道如何將密文加密解密。
這種加密方式固然很好,但是問題就在于如何讓雙方知道秘鑰。因為傳輸數(shù)據(jù)都是走的網(wǎng)絡,如果將秘鑰通過網(wǎng)絡的方式傳遞的話,一旦秘鑰被截獲就沒有加密的意義的。
非對稱加密:
有公鑰私鑰之分,公鑰所有人都可以知道,可以將數(shù)據(jù)用公鑰加密,但是將數(shù)據(jù)解密必須使用私鑰解密,私鑰只有分發(fā)公鑰的一方才知道。
這種加密方式就可以完美解決對稱加密存在的問題。假設現(xiàn)在兩端需要使用對稱加密,那么在這之前,可以先使用非對稱加密交換秘鑰。
簡單流程如下:首先服務端將公鑰公布出去,那么客戶端也就知道公鑰了。接下來客戶端創(chuàng)建一個秘鑰,然后通過公鑰加密并發(fā)送給服務端,服務端接收到密文以后通過私鑰解密出正確的秘鑰,這時候兩端就都知道秘鑰是什么了。
TLS 握手過程如下圖:
客戶端發(fā)送一個隨機值以及需要的協(xié)議和加密方式。
服務端收到客戶端的隨機值,自己也產(chǎn)生一個隨機值,并根據(jù)客戶端需求的協(xié)議和加密方式來使用對應的方式,并且發(fā)送自己的證書(如果需要驗證客戶端證書需要說明)
客戶端收到服務端的證書并驗證是否有效,驗證通過會再生成一個隨機值,通過服務端證書的公鑰去加密這個隨機值并發(fā)送給服務端,如果服務端需要驗證客戶端證書的話會附帶證書
服務端收到加密過的隨機值并使用私鑰解密獲得第三個隨機值,這時候兩端都擁有了三個隨機值,可以通過這三個隨機值按照之前約定的加密方式生成密鑰,接下來的通信就可以通過該密鑰來加密解密
通過以上步驟可知,在 TLS 握手階段,兩端使用非對稱加密的方式來通信,但是因為非對稱加密損耗的性能比對稱加密大,所以在正式傳輸數(shù)據(jù)時,兩端使用對稱加密的方式通信。
備注:以上說明的都是 TLS 1.2 協(xié)議的握手情況,在 1.3 協(xié)議中,首次建立連接只需要一個 RTT,后面恢復連接不需要 RTT 了。
小結
這篇文章的內(nèi)容還是相對比較多的,需要同學們多次閱讀,慢慢理解,里面有些術語如果不太懂的同學可以去網(wǎng)上學習一下,下面總結一下內(nèi)容:
- 介紹了HTTP、HTTPS和TSL之間的關系
- 詳細介紹HTTP的請求內(nèi)容和狀態(tài)碼
- 介紹TLS 中經(jīng)常用到的兩種加密方式以及握手的流程