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






