<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          HTTP協(xié)議與HTTPS的加密流程

          共 7942字,需瀏覽 16分鐘

           ·

          2020-12-14 11:31

          走過路過不要錯過

          點擊藍字關注我們


          一、HTTP基礎知識

          HTTP全稱Hyper Text Transfer Protocol,即超文本傳輸協(xié)議。HTTP是一個應用層協(xié)議,可視為一個在計算機世界里專門在兩點之間傳輸文字、圖片、音頻、視頻等超文本數據的約定和規(guī)范。

          1. HTTP請求流程

          我們這里就直接以一個常見的面試題引入啦。

          在瀏覽器中輸入 www.baidu.com 后會發(fā)生什么?

          當一個用戶在瀏覽器里輸入?www.baidu.com?這個 URL 時,將會發(fā)生很多操作。首先它會請求 DNS 把這個域名解析成對應的 IP 地址,然后根據這個 IP 地址在互聯(lián)網上找到對應的服務器,向這個服務器發(fā)起一個GET 請求,由這個服務器決定返回默認的數據資源給訪問用戶。在服務器端實際上還有很復雜的邏輯:服務器可能有好多臺,到底指定哪臺服務器來處理請求,這需要一個負載均衡設備來平均分配所有用戶的請求;還有請求的數據是存儲在分布式緩存里還是一個靜態(tài)文件中,或是在數據庫里;當數據返回瀏覽器時,瀏覽器解析數據發(fā)現(xiàn)還有一些靜態(tài)資源(如 CSS、JS 或者圖片)時又會發(fā)起另外的 HTTP 請求,而這些請求有可能會在 CDN 上,那么 CDN 服務器又會處理這個用戶的請求,大體上一個用戶請求會涉及這么多操作。每一個細節(jié)都會影響這個請求最終是否會成功。

          我們不去涉及其中過多的知識,單說HTTP的請求流程即可,從上面我們知道,HTTP協(xié)議是由客戶端發(fā)起的,由請求和響應構成,是一個標準的客戶端服務器模型(C/S),它的具體流程如下:

          1. 地址解析。域名系統(tǒng)DNS解析域名得到主機的IP地址;

          2. 封裝HTTP請求數據包。封裝的內容有以上部分結合本機自己的信息;

          3. 封裝成TCP包,建立TCP連接(TCP的三次握手);

          4. 客戶機發(fā)送請求命令。建立連接后,客戶機向服務器發(fā)送一個請求;

          5. 服務器響應。服務器接到請求后,給予相應的響應信息;

          6. 服務器關閉TCP連接。一般Web服務器向瀏覽器發(fā)送了請求數據,它要關閉TCP連接;

          7. 客戶端解析報文。客戶端接收到響應報文后解析HTML代碼,并渲染。

          2. 常見狀態(tài)碼

          HTTP常見的狀態(tài)碼分為五大類,如下表所示:

          狀態(tài)碼類別具體含義常見狀態(tài)碼
          1xx提示信息,表示目前是協(xié)議處理的中間狀態(tài),還需要后續(xù)的操作
          2xx成功,報文已經收到并被正確處理200、204、206
          3xx重定向,資源位置發(fā)生變動,需要客戶端重新發(fā)送請求301、302、304
          4xx客戶端錯誤,請求報文有誤,服務器無法處理;400、403、404
          5xx服務器錯誤,服務器在處理請求時內部發(fā)生了錯誤。500、501、502、503
          • 1xx:1xx類狀態(tài)碼屬于提示信息,是協(xié)議處理中的一種中間狀態(tài),實際用到的比較少。

          • 2xx:2xx類狀態(tài)碼表示成功處理了客戶端需求,也是我們?yōu)g覽器發(fā)起請求時常見的狀態(tài):

            • 【200 OK】:最常見的成功狀態(tài)碼,表示一切正常。如果是非HEAD請求,服務器返回的響應頭都會有 body 數據;

            • 【204 No Content】:也是常見的成功狀態(tài)碼,與 200 OK 基本相同,但響應頭沒有 body 數據;

            • 【206 Partial Content】:是應用于 HTTP 分塊下載或斷點續(xù)傳,表示響應返回的 body 數據并不是資源的全部,而是其中的一部分,也是服務器處理成功的狀態(tài);

          • 3xx:3xx類狀態(tài)碼表示客戶端請求的資源發(fā)生了變動,需要客戶端用新的 URL 重新發(fā)送請求獲取資源,也就是重定向

            注:301 和 302 都會在響應頭里使用Location,指明后續(xù)要跳轉的 URL,瀏覽器會自動重定向新的 URL。

            • 【301 Moved Permanently】:表示永久重定向,說明請求的資源已經不存在了,需改用新的 URL 再次訪問;

            • 【302 Found】:表示臨時重定向,說明請求的資源還在,但暫時需要用另一個 URL 來訪問;

          • 4xx:4xx類狀態(tài)碼表示客戶端發(fā)送的報文有誤,服務器無法處理,也就是錯誤碼的含義:

            • 【400 Bad Request】:表示客戶端請求的報文有錯誤,但只是個籠統(tǒng)的錯誤;

            • 【403 Forbidden】:表示服務器禁止訪問資源,并不是客戶端的請求出錯;

            • 【404 Not Found】:表示請求的資源在服務器上不存在或未找到,所以無法提供給客戶端。

          • 5xx:5xx類狀態(tài)碼表示客戶端請求報文正確,但是服務器處理時內部發(fā)生了錯誤,屬于服務器端的錯誤碼:

            • 【500 Internal Server Error】:與400類似,是個籠統(tǒng)通用的錯誤碼,服務器發(fā)生了什么錯誤,我們并不知道;

            • 【501 Not Implement】:表示客戶端請求的功能還不支持,類似”即將開業(yè),盡情期待“的意思;

            • 【502 Bad Gatwy】:通常是服務器作為網關或代理時返回的錯誤碼,表示服務器自身工作正常,訪問后端服務器發(fā)生了錯誤;

            • 【503 Service Unavailable】:表示服務器當前很忙,暫時無法響應服務器,類似”網絡服務正忙,請稍后重試“的意思。

          3. 常見字段

          首先我們了解一下HTTP的報文結構,大概如下:

          這是常見的請求報文,當然還有響應報文,兩者之間并不完全一致,這里只簡單提及一下請求報文的格式。

          首先是請求方法,常見的請求方法有 GET和POST兩種,之后跟著的是URL,即要訪問的地址,再后面跟著的就是協(xié)議版本,如:HTTP/1.1。

          我們主要講解之后跟著的字段,即請求頭,請求頭的字段常以key-value的形式,即”屬性名:屬性值“的形式傳遞若干數據,服務端據此獲取客戶端的信息。接下來我們就來了解常見的字段:

          • Accept字段與Content-type字段:

          Accept字段用于客戶端向服務器發(fā)送報文時表示自己可接收的響應內容類型,如:Accept:text/plain?(文本類型);

          類似的字段還有Accept-Charset?表示可接收的字符集;Accept-Encoding表示可接受的響應內容的壓縮方式 ;Accept-Language表示可接受的響應內容語言列表;Accept-Datetime表示可接受的按照時間來表示的響應內容版本。

          Content-Type字段用于服務器回應時,告訴客戶端,本次數據的格式是什么。

          類似的字段還有Content-Encoding字段表示數據的壓縮方法,表示服務器返回的數據使用什么壓縮格式。

          • Host字段

            Host字段用于客戶端發(fā)送請求時,用來指定服務器的域名。例如:Host:www.baidu.com。這里需要與報文中的請求行的 URL 區(qū)分,Host字段與 URL 組成完整的請求URL,例如請求行中的URL為/getPerson,而Host字段為www.baidu.com,那么兩者結合起來就是www.baidu.com/getPerson

          • Connection字段

            Connection字段最常用于客戶端要求服務器使用 TCP 持久連接,以便其他請求復用。

            Copy
            Connection: keep-alive

            擴展:

            • HTTP是無狀態(tài)的面向連接的協(xié)議,無狀態(tài)并不代表HTTP不能保持TCP連接,HTTP使用的不是UDP(無連接);

            • HTTP/1.1 版本的默認連接都是持久連接,但為了兼容老版本的 HTTP,需要指定Connection首部字段的值為Keep-Alive。簡單的說,當一個網頁打開完成后,客戶端和服務器之間用于傳輸的 HTTP 數據的 TCP 連接不會立刻關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續(xù)使用這一條已經建立的連接;

            • Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。

          • Content-Length字段

            服務器在返回數據時,會有Content-Length字段,表明本次回應的數據長度。例如:Content-Length: 1000,這表明了服務器本次回應的數據長度是1000個字節(jié),后面的字節(jié)就屬于下一個回應了。

          二、 HTTP存在的問題

          1. 性能問題

          在 HTTP/1.0 中有很大的性能問題,每次發(fā)起一個HTTP請求,都需要去建立一次TCP連接,而且還是串行請求,這使得 HTTP 在 TCP 的連接建立上花費了大量的開銷。對于這種問題,HTTP/1.1 中提出了長連接的通信方式,也叫持久連接。這種連接的好處在于減少了 TCP 連接的重復建立和斷開所造成的額外開銷,減輕了服務器端的負載:

          HTTP/1.1 采用了長連接的方式,這使得管道(Pipeline)網絡傳輸成為了可能。即可在同一個 TCP 連接里面,客戶端可以發(fā)起多個請求,只要第一個請求發(fā)出去了,不必等其回來,就可以發(fā)第二個請求出去,可以減少整體的響應時間。

          但是服務器還是按照順序,先回應第一個請求,完成后再回應第二個請求,以此類推。要是前面的請求回應得特別慢,后面就會有許多請求阻塞著,這就是所謂的【隊頭阻塞】。

          所以 HTTP/1.0 或是 HTTP/1.1 性能都不是很完美,所以后續(xù)會有其他加強。

          2. 安全問題

          HTTP的內容是明文傳輸的,明文數據會經過中間代理服務器、路由器、WIFI熱點、通信服務運行商等多個物理節(jié)點,如果信息在傳輸過程中被劫持,傳輸的內容久完全暴露了,劫持者還可以篡改傳輸的信息且不被雙方察覺,這就是中間人攻擊

          總結一下,HTTP在安全方面有以下三個問題:

          • 使用明文通信,一些重要的內容會被竊聽;

          • 不能驗證對方身份,可能是偽造的信息;

          • 無法驗證報文的完整性,有可能被修改;

          三、HTTPS的實現(xiàn)

          針對上面我們提到的HTTP的安全問題,HTTPS 在 HTTP 的基礎上增加了加密處理、認證機制和完整性保護,我們可以將?HTTPS = HTTP + 加密 + 認證 + 完整性保護

          1. 加密

          因為 HTTP 使用明文傳輸,中間會經過多個物理節(jié)點,可能會被劫持竊聽,針對這一問題,HTTPS 采用了加密的方式解決。最容易理解的就是對稱加密。

          1.1 對稱加密

          對稱加密好理解,就是我們擁有一個密鑰,它可以用來對一段內容進行加密,同樣的,在內容被進行加密后,需要用同一個密鑰對加密內容進行解密,才能看到原本的內容,可以看作我們日常生活中的鑰匙。

          HTTP 可以直接使用對稱加密嗎?

          當然不可以。如果通信雙方各自持有同一個密鑰,且沒有第三方知曉,那么這兩方之間的通信安全是可以被保證的(畢竟密鑰被破解可能性不大)。問題是”如何使得這個密鑰可以讓傳輸的雙方知曉,同時不被別人知道“?

          假如我們現(xiàn)在瀏覽器生成一個密鑰然后發(fā)送到服務端,告訴服務端我們雙方用這個密鑰來加密傳輸文件。或者是放過來,由服務器生成密鑰然后發(fā)送給瀏覽器。很明顯這就不現(xiàn)實,我們知道 HTTP 傳輸時中間是需要經過許多個中間節(jié)點的,在經過中間節(jié)點時這個密鑰被劫持下來是一件十分容易的事,所以這種方式不可取。由此引入非對稱加密

          1.2 非對稱加密

          非對稱加密有兩把密鑰,通常一把叫做公鑰,另外一把叫做私鑰。用公鑰加密的內容必須用私鑰才能解開,同樣的,私鑰加密的內容需要用公鑰才能解開。

          HTTP 可以直接使用非對稱加密嗎?

          還是不可以。鑒于非對稱加密的性質,我們可能會有這種思路:服務器先把公鑰直接明文傳輸給瀏覽器,之后瀏覽器向服務器傳數據前都先用這個公鑰加密好再傳輸,這條數據似乎可以保障了,因為只有服務器端的相應私鑰能解開這條數據。但是這樣還是有問題,密鑰還是可以被劫持的。

          如果服務器用它的的私鑰加密數據傳給瀏覽器,那么瀏覽器用公鑰可以解密它,而這個公鑰是一開始通過明文傳輸給瀏覽器的,如果這個公鑰被誰劫持到的話,他也能用該公鑰解密服務器傳來的信息了。所以這種方式的實現(xiàn)還是會有問題,似乎只能保證由瀏覽器傳輸數據時的安全性(其實還有漏洞)。

          1.3 改良版非對稱加密

          通過一組公鑰、私鑰已經能保證單個方向傳輸的安全性,那用兩組公鑰私鑰是不是就能保證雙向傳輸都安全了,以下面流程為例:

          1. 某網站擁有用于非對稱加密的公鑰 A、私鑰 A‘,瀏覽器擁有用于非對稱加密的公鑰 B、私鑰 B’ ;

          2. 瀏覽器向網站服務器發(fā)起請求,服務器把公鑰 A 明文傳輸給瀏覽器;

          3. 瀏覽器將公鑰 B 明文傳輸給服務器;

          4. 之后瀏覽器向服務器傳輸的所有東西都用公鑰 A 加密,服務器收到后用私鑰 A’ 解密。由于只有服務器擁有這個私鑰 A’ 可以解密,所以能保證這條數據的安全;

          5. 服務器向瀏覽器傳輸的所有東西都用公鑰 B 加密,瀏覽器收到后用私鑰 B’ 解密。同上也可以保證這條數據的安全。

          這種實現(xiàn)方式理論上確實可行,拋開這里面仍有的漏洞不談(下文再述),HTTPS 的加密卻沒有使用這種方案,為什么?

          最主要的原因是非對稱加密算法非常耗時,特別是加密解密一些較大數據的時候有些力不從心。相比之下,對稱加密就要快很多,那能不能同時運用對稱加密與非對稱加密的性質來實現(xiàn)對 HTTP 的加密呢?

          1.4 混合加密

          既然非對稱加密耗時,那么就用“對稱加密 + 非對稱加密”結合的形式來實現(xiàn)對 HTTP 的加密,而且還得盡量減少非堆成加密的次數 ,這樣是否能實現(xiàn)呢?

          這種方式是可以實現(xiàn)的,而且非對稱加密、解密各只需要用一次即可。請看以下過程:

          1. 某網站擁有非對稱加密的公鑰 A、私鑰 A‘ ;

          2. 瀏覽器向網站服務器發(fā)起請求,服務器把公鑰 A 明文傳輸給瀏覽器;

          3. 瀏覽器隨機生成一個用以對稱加密的密鑰 X,用公鑰 A 加密后傳給服務器;

          4. 服務器端拿到加密的密鑰后,用公鑰 A 解密得到密鑰 X;

          5. 這樣雙方就都擁有密鑰 X 了,且別人無法知道它,之后雙方所有數據都用密鑰 X 進行加密解密。

          HTTPS 基本上就是采用了這種方案了,當然這種方法還是有漏洞,我們接著往下講。

          2. 認證

          2.1 中間人攻擊

          根據上面的混合加密過程,中間人確實無法擁有瀏覽器生成的對稱密鑰 X,這個密鑰本身就被公鑰 A 給加密了,只有服務器才能通過私鑰 A‘ 對其進行解密。然而在這個過程中中間人完全不需要獲取到密鑰 A’ 就能進行攻擊了。如下流程所示:

          1. 某網站擁有用于非對稱加密的公鑰A、私鑰A’ ;

          2. 瀏覽器向網站服務器發(fā)起請求,服務器把公鑰 A 明文給傳輸瀏覽器;

          3. 中間人劫持到公鑰A,保存下來,把數據包中的公鑰A替換成自己偽造的公鑰B(它當然也擁有公鑰B對應的私鑰B’)

          4. 瀏覽器隨機生成一個用于對稱加密的密鑰X,用公鑰B(瀏覽器不知道公鑰被替換了)加密后傳給服務器;

          5. 中間人劫持后用私鑰 B’ 解密得到密鑰 X,再用公鑰 A 將 X 加密后傳給服務器

          6. 服務器拿到后用私鑰A’解密得到密鑰X。

          這樣在雙方都不會發(fā)生異常的情況下,中間人得到了密鑰 X,這其中的根本原因就是瀏覽器無法確認自己收到的公鑰是不是網站的。那么接下來就是要解決這一問題。

          2.2 數字證書

          如何證明瀏覽器收到的公鑰一定是該網站的公鑰?這里就需要有一個公信機構給網站頒發(fā)一個“身份證”了。網站在使用 HTTPS 前,需要向“CA機構”申請頒發(fā)一份數字證書,數字證書里有證書持有者、證書持有者的公鑰等信息,服務器把證書傳輸給瀏覽器,瀏覽器從證書里取公鑰就行了,證書就如同身份證一樣,可以證明“該公鑰對應該網站”。

          然而到這里還是有一個問題,如何保證證書在傳輸的過程不會被篡改,身份證本身有防偽的技術,那么如何保證證書的防偽呢?

          2.3 數字簽名

          如何保證證書不被篡改?

          我們把證書內容生成一份“簽名”,比對證書內容和簽名是否一致就能察覺是否被修改,這種技術就稱為數字簽名

          數字簽名的制作過程?

          1. CA 擁有非對稱加密的私鑰和公鑰;

          2. CA 對證書明文信息進行 Hash;

          3. 對 Hash 后的值用私鑰加密,得到數字簽名S;

          將明文和數字簽名共同組成數字證書,這樣一份證書就可以頒發(fā)給網站了。

          瀏覽器得到證書后如何驗證這份證書的真實性?

          1. 拿到服務器發(fā)送過來的證書,得到明文T,數字簽名S;

          2. 用CA機構的公鑰對 S 解密(由于是瀏覽器信任的機構,所以瀏覽器保有CA的公鑰),得到S‘;

          3. 瀏覽器用證書說明的 Hash 算法對明文 T 進行 Hash 得到 T’;

          4. 比較 S‘ 是否等于 T’,等于則代表證書可信。

          瀏覽器如何得到權威機構的公鑰?

          上面提到,如何要對服務器發(fā)過來的證書進行解密,那么就需要到CA的公鑰,因為其被CA的私鑰給加密了。那么瀏覽器是如何擁有CA的公鑰呢?

          實際上權威機構的公鑰并不需要傳輸,因為權威機構會和主流的瀏覽器或操作系統(tǒng)合作,將他們的公鑰內置在瀏覽器或操作系統(tǒng)環(huán)境中。客戶端收到證書之后,只需要從證書中找到權威機構的信息,并從本地環(huán)境中找到權威機構的公鑰,就能正確解密A公鑰。當然實際情況要比這個復雜得多,這里簡單介紹就行。

          中間人有可能篡改證書嗎?

          上面我們提到,權威機構的公鑰是可能在瀏覽器或操作系統(tǒng)中的,那么中間人劫持到證書后是可以解密得到原文的。相應的,他也可以去篡改證書的原文,但是由于他沒有 CA 機構的私鑰,無法相應地篡改簽名。所以瀏覽器收到證書后會發(fā)現(xiàn)原文和解密后的值不一致,說明證書已經被篡改,證書不可信了,所以中間人不可能去篡改證書了。

          四、HTTPS的請求流程

          1. 客戶端向服務器發(fā)起 HTTPS 請求,連接到服務器的 443 端口;

          2. 服務器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,服務器端保存著私鑰,不能將其泄露,公鑰可以發(fā)送給任何人;

          3. 服務器將自己的公鑰包含在權威機構發(fā)布的證書中發(fā)送給客戶端;

          4. 客戶端收到服務器端的證書之后,會對證書進行檢查,驗證其合法性,如果發(fā)現(xiàn)發(fā)現(xiàn)證書有問題,那么HTTPS傳輸就無法繼續(xù)。嚴格的說,這里應該是驗證服務器發(fā)送的數字證書的合法性,關于客戶端如何驗證數字證書的合法性。如果公鑰合格,那么客戶端會生成一個隨機值,這個隨機值就是用于進行對稱加密的密鑰,我們將該密鑰稱之為client key,即客戶端密鑰,這樣在概念上和服務器端的密鑰容易進行區(qū)分。然后用服務器的公鑰對客戶端密鑰進行非對稱加密,這樣客戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束;

          5. 客戶端會發(fā)起 HTTPS 中的第二個 HTTP 請求,將被公鑰所加密之后的客戶端密鑰發(fā)送給服務器;

          6. 服務器接收到客戶端發(fā)來的密文之后,會用自己的私鑰對其進行非對稱解密,解密之后的明文就是客戶端密鑰,然后用客戶端密鑰對數據進行對稱加密,這樣數據就變成了密文。

          7. 然后服務器用對稱加密的密鑰(即客戶端密鑰)對報文進行加密,并將加密后的報文發(fā)送給客戶端;

          8. 客戶端收到服務器發(fā)送來的密文,用客戶端密鑰對其進行對稱解密,得到服務器發(fā)送的數據。這樣 HTTPS 中的第二個 HTTP 請求結束,整個 HTTPS 傳輸完成。

          文章內容絕大數來源網絡,我只是個搬運工,若有哪里出錯,請評論區(qū)指出。




          往期精彩推薦



          騰訊、阿里、滴滴后臺面試題匯總總結 — (含答案)

          面試:史上最全多線程面試題 !

          最新阿里內推Java后端面試題

          JVM難學?那是因為你沒認真看完這篇文章


          END


          關注作者微信公眾號 —《JAVA爛豬皮》


          了解更多java后端架構知識以及最新面試寶典


          你點的每個好看,我都認真當成了


          看完本文記得給作者點贊+在看哦~~~大家的支持,是作者源源不斷出文的動力


          作者:?周二鴨

          出處:https://www.cnblogs.com/jojop/p/14111938.html

          瀏覽 84
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费在线AⅤ视频 | 免费草逼网站 | 贵族学校极品粉穴清纯学生妹 | 国产精品美女在线 | 国产精品成人自拍 |