?
響應報文格式
響應報文格式由首行,響應頭(header),空行,正文(body) 組成
響應報文首行包括
1.版本號? 如HTTP/1.1??
2.狀態碼(如200)??描述了請求的結果??
3.狀態碼描述(如OK)? ?
首行——狀態碼
這里主要介紹一下響應報文里面的 狀態碼?和狀態碼描述,它們描述了這次HTTP請求是否成功以及失敗的原因
信息類(1xx)
? 這里的狀態碼大體意思就是表示請求已被接收,但需要客戶端繼續發送請求,很少用到這里的狀態碼。
成功類(2xx)
?這里的狀態碼表示請求已成功處理,200 ok 是我們最常見的一個狀態碼,表示訪問成功.
重定向類(3xx)
? ?3xx 表示 重定向。重定向指的是請求中訪問的是 A 這樣的地址,響應返回了一個重定向報文,告訴你應該要訪問 B 地址
很多時候,頁面跳轉,就可以通過重定向來實現,還有的時候,某個網站服務器遷移了. IP/域名變了,就可以給舊的地址掛一個重定向響應,訪問舊地址的用戶就自動跳轉到新的地址
這里有兩個常見的狀態碼
301 Moved Permanently(永久重定向)
含義:請求的資源已永久移動到新的位置。
?302 Found(臨時重定向)
含義:請求的資源臨時移動到新的位置。
客戶端錯誤類(4xx)
? 表示客戶端的請求有誤,服務器無法處理。
? 常見狀態碼:
? 400 Bad Request:請求格式錯誤。
? 401 Unauthorized:請求需要用戶認證。
? 403 Forbidden:服務器拒絕請求(權限不足)。
? 404 Not Found:請求的資源不存在。
? 405 Method Not Allowed:請求方法不被允許(如 GET 請求不允許使用 POST)。
? 服務器錯誤類(5xx)
表示服務器在處理請求時發生了錯誤。
常見狀態碼:
500 Internal Server Error:服務器內部錯誤。
501 Not Implemented:服務器不支持請求的方法。(get或者post)
503 Service Unavailable:服務器暫時不可用(如過載或維護)。
?響應頭
響應頭 (header)跟請求頭結構一樣,鍵值對內容跟請求頭差別沒有很大,以下是響應頭鍵值對的主要內容:
唯一要說的點就是content-typent,由于這是響應報文,響應報文里絕對會有body內容,body里的內容可能比較長, 會有多種格式,如HTML, CSS, JS, JSON, XML, 圖片, 字體, 視頻, 音頻等,比請求報文里的body種類多好多。
回顧一下
請求報文中body內部的數據類型,有以下三種數據類型
1.json,具體類型為 application/json
2.form表單的格式,具體類型為application/x-www-form-urlencoded:form
3.form-data 的格式,multipart/form-data: form?
除此以外,空行依舊是響應頭的結束標志,body我們響應頭該提的都提了,這里也不多說了
如何構造HTTP請求?
在講完HTTP協議的報文結構后,我們接下來就要去了解下面兩個問題
如何讓客戶端構造一個 HTTP 請求?
如何讓服務器處理一個 HTTP 請求 ?
處理請求涉及到Servlet/Spring ,它非常重要,要講清楚如何處理要花非常多的時間,所以這里我們就先只講如何構造一個HTTP請求。
首先我們能直接在瀏覽器 地址欄 輸入 url, 此時構造了一個 GET 請求, 又或者在htm| 中, 一些特殊的 htm| 標簽, 可能會構造?GET 請求,比如像 img, a, link, script。
如果通過代碼的話,我們能通過form或者是ajax的方式去構造,這里都是前端代碼,就不說了
除此以外還有一種代碼的方式,通過Java scoket構造HTTP請求,所謂的 "發送 HTTP 請求", 本質上就是按照 HTTP 的格式往 TCP Socket 中寫入一個字符串. 所謂的 "接受 HTTP 響應", 本質上就是從 TCP Socket 中讀取一個字符串, 再按照 HTTP 的格式來解析. 我們基于 Socket 的知識, 完全可以構造出一個簡單的 HTTP 客戶端程序, 用來發送各種類型的 HTTP 請求。除了這些以外,我們還能通過第三方軟件去快捷生成HTTP請求,這是最方便的,這里我們推薦用postman軟件
HTTPS協議?
當前網絡上,主要都是 HTTPS 了,很少能見到 HTTP
實際上 HTTPS 也是基于 HTTP,前面講過的 HTTP 的各個方面的內容, 對于 HTTPS 同樣適用,報文結構都是一樣的。只不過 HTTPS 在 HTTP 的基礎之上, 引入了"加密"機制.
引入 HTTPS 防止你的數據被黑客篡改(尤其是反針對??運營商劫持) ---運營商可能修改廣告訪問次數來和企業合作獲利
加密機制是什么?
明文:要傳輸的原始數據密文:經過加密之后得到的數據
密鑰:進行加密和解密過程的重要道具
加密就是把明文(要傳輸的信息)進行一系列變換,生成密文.解密就是把密文再進行一系列變換,還原成明文.
在這個加密和解密的過程中,往往需要一些數據才能進行轉換,這樣的數據稱為密鑰
既然要保證數據安全, 就需要進行 “加密”.
網絡傳輸中不再直接傳輸明文了, 而是加密之后的 “密文”.
加密的方式有很多, 但是整體可以分成兩大類:?對稱加密?和?非對稱加密
對稱加密其實就是通過同一個 “密鑰” , 把明文加密成密文, 并且也能把密文解密成明文。
?非對稱加密要用到兩個密鑰, 一個叫做 “公鑰”, 一個叫做 “私鑰”. (私鑰是自己必須嚴格保密的鑰匙,公鑰是公開發布給大家的鑰匙)
- 通過公鑰對明文加密, 變成密文
- 通過私鑰對密文解密, 變成明文
也可以反著用
- 通過私鑰對明文加密, 變成密文
- 通過公鑰對密文解密, 變成明文
公鑰和私鑰是配對的. 它最大的缺點就是運算速度非常慢,比對稱加密要慢很多.但安全性高
HTTPS保證自己的安全性過程?
在講完上述加密概念后,我們就能去講述HTTP如何保證自己的安全性了
但事情沒這么簡單. 要想進行對稱加密,就需要客戶端和服務器都具有同一個對稱密鑰,服務器同一時刻其實是給很多客戶端提供服務的. 這么多客戶端, 每個人用的秘鑰都必須是不同的(如果是相同那密鑰就太容易擴散了, 黑客就也能拿到了). 因此服務器就需要維護每個客戶端和每個密鑰之間的關聯關系,這是個極其累的事,如果還要服務器再生成密鑰的話就太負載了。
這個時候比較理想的做法, 讓每個客戶端生成一個密鑰,在客戶端和服務器建立連接的時候, 傳輸給服務器讓服務器也有。????
但是如果直接把密鑰明文傳輸, 那么黑客也就能獲得密鑰了,此時后續的加密操作就形同虛設了。
因此密鑰的傳輸也必須加密傳輸!
但是要想對密鑰進行對稱加密, 就仍然需要先協商確定一個 “密鑰的密鑰”. 這就無限套娃了. 此時密鑰的傳輸再用對稱加密就行不通了,我們就選擇用非對稱加密進行密鑰的傳輸。
引入非對稱加密
服務器會自己生成一對公鑰和私鑰,并且把自己生成的公鑰傳輸給客戶端,私鑰還是自己來持有。
接下來客戶端會對自己的對稱密鑰(每個客戶端生成自己的,客戶端之間不知道別人的對稱密鑰是啥),比如上圖的這個客戶端生成的對稱密鑰時六個8,此時這個六個8不會明文傳輸,通過剛才從服務器拿到的公鑰,來針對對稱密鑰進行加密,再把對稱密鑰的密文傳輸給服務器,這樣服務器就知道了對稱密鑰是什么。
此時黑客拿到對稱密鑰的數據之后,是無法解密的,使用公鑰加密,就得使用對應的私鑰來進行解密,黑客能輕松拿到公鑰,而拿不到私鑰,這樣是解密不了數據的。
我們要注意一個服務器只會生成一對公鑰和私鑰(意味著所有和它連接的客戶端都是用同一套公鑰進行加密)
既然已經引入了非對稱加密,為啥還需要引入對稱加密呢?直接使用非對稱加密,來完成所有業務數據的加密傳輸即可
這是因為進行非對稱加密/解密,運算成本是比較高的.運算速度也是比較低的,對稱加密運算成本低, 速度快.
使用非對稱加密kkkk,只是用來進行這種關鍵環節(傳輸密鑰)(一次性的工作,體積也不大),成本就比較可控后續要傳輸大量的業務數據,都使用效率更高的對稱加密,比較友好的做法.
如果業務數據都使用非對稱加密,整體的傳輸效率就會大打折扣了.
注意:上述流程看起來很美好,但是黑客依然能獲取到原始數據,通過中間人攻擊去獲取。
中間人攻擊問題
下面我們說下中間人攻擊的流程:
客戶端訪問服務器(黑客冒充的),請求公鑰,服務器就會生成一對公鑰和私鑰(提前生成好的),在此我們稱為pub,pri,然后把公鑰(pub)返回給黑客
這時就到了關鍵環節:黑客可以自己生成出一對公鑰(pub2)和私鑰(pri2),黑客就會把自己的公鑰(pub2)返回給客戶端,客戶端就無法區分出當前的pub2是不是服務器最開始返回的公鑰,是不是被中間人掉包了的公鑰,客戶端就只能選擇相信,客戶端就會拿著pub2針對對稱密鑰進行加密,并且發送給服務器(黑客),此時黑客就會拿著pir2針對剛才收到的pub2加密的數據進行解密,從而拿到這里的對稱密鑰,黑客繼續把拿到的對稱密鑰,使用服務器的公鑰pub再次加密發送給服務器,服務器就會使用自己的私鑰進行解密,此處肯定會解密成功,拿到對稱密鑰,接下里意味著客戶端和服務器就會繼續使用這個對稱密鑰來完成后續的業務數據加密,此時對稱密鑰已經泄露出去了
上述過程,黑客面對服務器的時候,扮演客戶端的角色,面對客戶端的時候,扮演服務器的角色,那么客戶端和服務器都不知道黑客的存在,這樣就很神秘的泄露出去了。
引入證書?
上面講到,客戶端無法區分拿到的公鑰是否為服務器返回的公鑰,還是說其他人偽造的公鑰。那么客戶端如果能做出區分,當前的公鑰是否為服務器返回的公鑰,中間人攻擊就不攻自破了。
為了解決該問題,我們引入第三方的可以被大家都信任的"公證機構",公證機構說這個公鑰是正確的,不是被偽造的,我們就是可以信任的。所有的服務器在上線自己的網站的時候,都要先去第三方公證機構申請一個證書(此處的證書并不是紙質的,而是數字證書,可理解為一串字符串數據),這個證書包含:發證機構,有效期,服務器的公鑰,證書持有者,持有者網站,主域名,數字簽名......
這個數字簽名可理解為一個加密之后的校驗和,校驗和是基于CRC/MD5等方式,把證書的其他內容的每個字節都帶入計算一遍,最終得到的一串字符串,然后針對校驗和進行非對稱加密的方式進行加密,那么是誰的私鑰進行加密的呢?
公證機構自己會生成一對公鑰和私鑰(和服務器的公鑰私鑰不一樣),公證機構會自己持有私鑰,而每個電腦的操作系統都會內置公證機構的公鑰,公證機構會拿自己的私鑰針對證書數據的校驗和進行加密,得到數字簽名。
在申請了證書后,我們就不再發送公鑰了,而是直接發送證書(證書里面包含公鑰)
客戶端拿到了證書,也就拿到了證書中的公鑰,客戶端就需要驗證這個公鑰是否是服務器最初的公鑰(是否是被黑客篡改了)
這個過程就稱為證書的校驗,如何進行校驗?此時,客戶端拿到了數字簽名,就可以通過操作系統內置的公證機構的公鑰進行解密了,得到最初的校驗和,客戶端再重新計算一遍這里的校驗和,和解密出來的校驗和進行對比,如果校驗和一致,就可以認為證書沒有被篡改過,公鑰就是可信的
在上述機制下,黑客就無法對證書內容進行篡改了,即使篡改,也很容易被發現.
當黑客收到證書之后,如果直接修改里面的公鑰,替換成自己的,客戶端在進行證書校驗的時候,就會發現校驗和不一致了,客戶端就可以認為是篡改過了.(客戶端這邊往往就會彈出一些對話框來警告用戶,存在安全風險)
那么黑客在替換公鑰時,同時替換掉數字簽名是否可以呢?在算出自己的校驗和時,針對校驗和加密,需要使用公證機構的私鑰才能進行.黑客沒有這個私鑰.如果黑客拿自己的私鑰加密,客戶端也就無法使用公證機構的公鑰解密了公證機構的公鑰是客戶端系統自帶的,黑客也無法替換(如果不對校驗和進行加密,黑客還真可能得逞)
結合上述過程,證書就是可信的,通過了校驗,就說明公鑰就是服務器原始的公鑰了,完美解決了中間人攻擊問題
所以https是通過以下三點相結合保證 https 的安全性:
1.對稱加密,加密業務數據2.非對稱加密,加密對稱密鑰
3.使用證書,校驗服務器的公鑰這是一道經典的面試題,我們要深刻的理解它。
?
?