HTTP 和 HTTPS 的主要區別在於 HTTP 協議傳遞的是明文數據,而 HTTPS 傳遞的是加密過的數據,也就是說 HTTPS 更具備安全性。也正由 HTTPS 須要保證安全性,因此它的性能要比 HTTP 差一點。web
單說安全性確定是不夠的,我打算擴展講一下 HTTPS 是怎麼解決安全性問題的,經過這些 HTTP 沒有機制,反映出 HTTPS 與 HTTP 的區別。下面嘗試把 HTTPS 加密的過程推導出來。推導過程不涉及複雜的實現細節:如何安全地進行數據傳輸?面試
假設如今 A 和 B 要進行安全的通訊,那麼究竟怎樣纔算是安全的通訊?很天然地會想到:A 和 B 之間傳遞數據,這些數據只有 A 和 B 纔看得懂,中間人就算截取了信息但也看不懂,這纔算得上安全。redis
安全通訊的處理手段:算法
爲了能讓 A 和 B 才能看懂,就必需要對數據進行加密,並且首先想到的就是對稱加密。對稱加密的意思是 A 和 B 各持有一個相同的密鑰,它們傳遞信息時會用密鑰給信息加密,在消息到達端給消息解密,完成安全通訊。數據庫
在對稱加密中又會涉及到加密算法的選擇問題。現實世界中,一般是多個客戶端面向一個服務器的狀況,不可能讓每一個客戶端和服務器之間都採用相同的加密算法,若是是這樣那和沒加密差很少。因此註定每一個客戶端和服務器之間都會採用不一樣的加密方式。如何讓每一個客戶端與服務器之間都採用不一樣的加密方式?小程序
要想對不一樣的機器使用不一樣的加密方式,最直接想到的就是使用隨機數。也就說客戶端和服務器之間每次都基於一個隨機數產生加密算法。(具體實現時爲了保證隨機,用到還不止一個隨機數)後端
這個產生加密算法的過程稱之爲協商,如今問題是協商的過程是透明的,也就是說中間人能夠截獲協商的過程,從而知道咱們的加密方式。爲了解決這個問題,咱們須要對協商的過程進行加密。如何對協商的過程進行加密?瀏覽器
之因此能來到這一步,是由於咱們一開始就選擇使用了對稱加密,也就說一開始的對稱加密緻使瞭如今的問題,因此這時咱們不能再使用對稱加密了,不然會陷入死循環。緩存
在密碼學領域,還有一種加密過程叫非對稱加密,它的邏輯是這樣的:通訊雙方一方持有私鑰,一方持有公鑰,通過私鑰加密的信息,都能經過公鑰進行解密。可是通過公鑰加密的數據,只有私鑰能夠解密。安全
按照非對稱加密的規則,咱們讓服務器持有私鑰,讓客戶端持有公鑰。這樣就能保證客戶端給服務器發送消息的時候是安全的(相反,服務器給客戶端發送消息就是不安全的),咱們能夠把協商時重要的邏輯安排在客戶端給服務器發送信息的過程當中,從而保證了協商過程的安全性。客戶端如何得到公鑰?
如今用非對稱加密算法解決了協商的安全問題,可是非對稱加密的前提是客戶端須要得到公鑰,這又是一個問題了,客戶端與服務器打交道以前是互不知道雙方身份的,怎麼才能讓客戶端得到公鑰呢?
也就只有兩種辦法:
客戶端向服務器要公鑰
客戶端向一個遠程的公共服務器獲取公鑰
方法2顯然是不行的,尚且不說多了一個訪問節點,如何找到公共服務器的地址也是一個待解決的問題,因此仍是使用方法1。可是方法 1 存在一個問題:若是中間人把服務器發送給客戶端的公鑰調包了怎麼辦?也就是說客戶端沒法知道發送公鑰的是不是正真的服務器。
引入第三方機構解決問題
客戶端沒法辨識服務端和中間人的問題稱爲「身份驗證」問題,也就是說咱們須要爲服務器向客戶端發送公鑰的過程進行加密。
這下完了,以前咱們因遇到對稱加密的瓶頸選擇了非對稱加密,如今使用非對稱加密也遇到了瓶頸。顯然這兩種加密方式都是不可用的了,不然會再次陷入死循環。
接下來咱們只好經過第三方機構的介入,解決這個問題。首先咱們本身保存有第三方權威機構的公鑰,而後第三方機構使用私鑰對服務器將要發送給客戶端的公鑰進行加密,客戶端接收到這個經加密的公鑰後(數字證書),就能經過本身保存的第三方機構公鑰進行解密。
到這裏爲止,咱們解釋了 HTTPS 中使用到的對稱加密,非對稱加密,CA,數字證書的概念,可是還差一個叫數字簽名的概念沒有解釋。
在現實生活中,CA 不單止會給咱們正常公司發放證書,還會給中間人的壞公司發放證書,若是中間人把發放的證書調包了怎麼辦?這時咱們仍能用 CA 的私鑰進行解密,可是證書已經被調包了。
那麼客戶端怎樣驗證證書的真僞呢?答案是證書自己會告訴客戶端如何辨認真僞。比方說證書上面有一個證書編號,還有一個如何計算證書編號的方法,客戶端能夠根據計算證書編號的方法計算出本身要得到的證書的編號,而後把這個編號和證書上的編號進行比對,若是同樣證實沒有被調包。
這裏的證書編號指的就是數字簽名,證書指的就是數字證書。
總結一下 HTTPS :HTTPS 想要保證客戶端與服務器之間的通訊安全,就得使用對稱加密算法進行加密。協商對稱加密算法的過程經過非對稱加密算法來保證。在非對稱加密算法中,客戶端得到公鑰的過程須要第三方機構(CA)經過頒發數字證書保證安全性。
總得來講經過這一系列機制協商出了一個對稱加密算法後,客戶端與服務器之間就能經過該算法進行安全的通訊了。
我的以爲這個問題還能夠擴展一下,試想一下在鍵入 URL 以前,也就是剛開完機的時候,須要聯網,而後才能上網。這個階段包括了獲取本機 IP 地址,獲取 DNS 服務器 IP 地址,得到網關路由器 IP 和 MAC 地址等操做,把這些一塊兒答上去會不會好一些?如下是回答:獲取本機 IP 地址,DNS 服務器地址,網關路由器地址。
首先咱們須要準備一個 DHCP 報文,封裝在一個 UDP 報文段中,裏面包括本機端口號 68 和目的端口號 67,而後到網絡層封裝成數據包裏面包括了本機的初始 IP 0.0.0.0,和廣播地址 255.255.255.255。接着到鏈路層封裝成鏈路層幀。裏面包括廣播地址和本機網卡的 MAC 地址。最後發送到本地局域網中。
這個數據包最終會被局域網中的 DHCP 服務器發現(有可能有多個 DHCP 服務器),DHCP 服務器會把可用的 IP 地址返回給咱們的主機。而後操做系統選擇一個 IP 地址併發送給 DHCP 服務器,最後 DHCP 服務器會返回一個包含本機 IP,DNS 服務器 IP,網關路由器 IP 的報文。
接下來咱們須要經過網關路由器的 IP 地址去得到網關路由器的 MAC 地址,這樣咱們才能夠把獲取網站 IP 的 DNS 請求報文由網關發送給 DNS 服務器。這時候咱們須要準備一個 ARP 請求報文,請求獲取網關路由器的 MAC 地址,這個報文一樣是以廣播的方式發送到局域網中,網關路由器接受到請求報文就會把本身的 MAC 地址返回給本機。
獲取域名的 IP 地址
接下來一切都準備好了,能夠開始講鍵入 URL 以後的事情了:
首先咱們要訪問 DNS 服務器得到網站對應的 IP 地址,這時咱們須要把 DNS 報文封裝到一個 UDP 報文中,進而封裝到網絡層的數據包中,填上源 IP,目的 DNS 服務器 IP 地址。接着封裝鏈路層,填上網卡 MAC 地址和網關路由器 MAC 地址。接下來這個 DNS 請求報文就會經網關路由器發送給 DNS 服務器。
咱們假設 DNS 服務器緩存有該網站的 IP 地址,(若是沒有緩存會進一步向更高級的DNS服務器索要IP地址)。接着 DNS 服務器會返回該域名的 IP 地址。
三次握手創建 TCP 鏈接
拿到了該網站的 IP 地址後就能夠與該網站的服務器創建 TCP 鏈接了。創建 TCP 鏈接須要通過三次握手,過程以下:(更詳細的過程在開頭)
本機的 TCP 首先生成一個不帶任何數據,SYN 標誌位爲 1,序號字段假設爲client_num 的 TCP 報文,通過下層一系列網絡棧後發送給目的 ip 服務器。
該服務器接受到 TCP 請求報文後,會迴應一個贊成鏈接的 TCP 報文,這個報文的 SYN 標誌位也會被置 1,序號字段假設爲 server_num,ACK 響應字段爲 client_num + 1。
接受到贊成鏈接的報文後,我方主機會進行響應,此次的 TCP 報文 SYN 位會被置0,序號字段爲 client_num + 1,ACK 響應字段爲 server + 1。而且此次的響應報文是能夠攜帶數據的。
創建鏈接後進行數據交互
在三次握手創建鏈接後,本機就能夠向服務器發送 HTTP 請求了,服務器接受到了請求會作出響應的響應,把請求的數據發送給本機瀏覽器,最終瀏覽器把服務器響應的數據渲染顯示出來,咱們就看到了五彩繽紛的網頁。八、HTTP的常見狀態碼有哪些,表明什麼含義?
首先狀態碼的開頭不一樣表明不一樣的類型:
1xx:表明指示信息,表示請求已接收,繼續處理 2xx:表明成功,表示請求已被成功接收,理解,接受 3xx:重定向,表示完成請求必須進行進一步的操做 4xx:客戶端錯誤,請求有語法錯誤或請求沒法實現 5xx:服務器端錯誤,服務器未能實現合法的請求
常見狀態碼:
200 OK:正常返回信息 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解 403 Forbidden:服務器收到請求,可是拒絕提供服務 404 Not Found:請求資源不存在,輸入了錯誤的URL 500 Internal Server Error:服務器發生不可預期錯誤 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
1.從 HTTP 報文層面來看,GET 請求將信息放在 URL,POST 將請求信息放在請求體中。這一點使得 GET 請求攜帶的數據量有限,由於 URL 自己是有長度限制的,而 POST 請求的數據存放在報文體中,所以對大小沒有限制。並且從形式上看,GET 請求把數據放 URL 上感受不太安全,而 POST 請求把數據放在請求體裏彷佛安全一些。實際上想要獲取 POST 請求中的內容仍是很容易的,所以二者在安全性上其實沒有太大差別,想要實現安全的信息傳輸仍是得靠 HTTPS。
2.從數據庫層面來看,GET 符合冪等性和安全性,而 POST 請求不符合。這個其實和 GET/POST 請求的做用有關。按照 HTTP 的約定,GET 請求用於查看信息,不會改變服務器上的信息;而 POST 請求用來改變服務器上的信息。正由於 GET 請求只查看信息,不改變信息,對數據庫的一次或屢次操做得到的結果是一致的,認爲它符合冪等性。安全性是指對數據庫操做沒有改變數據庫中的數據。
3.從其餘層面來看,GET 請求可以被緩存,GET 請求可以保存在瀏覽器的瀏覽記錄裏,GET 請求的 URL 可以保存爲瀏覽器書籤。這些都是 POST 請求所不具有的。緩存是 GET 請求被普遍應用的根本,他可以被緩存也是由於它的冪等性和安全性,除了返回結果沒有其餘多餘的動做,所以絕大部分的 GET 請求都被 CDN 緩存起來了,大大減小了 Web 服務器的負擔。
因爲 Http 協議是無狀態協議,若是客戶經過瀏覽器訪問 web 應用時沒有一個保存用戶訪問狀態的機制,那麼將不能持續跟蹤應用的操做。好比當用戶往購物車中添加了商品,web 應用必須在用戶瀏覽別的商品的時候仍保存購物車的狀態,以便用戶繼續往購物車中添加商品。
cookie 是瀏覽器的一種緩存機制,它可用於維持客戶端與服務器端之間的會話。因爲下面一題會講到 session,因此這裏要強調 cookie 會將會話保存在客戶端( session 則是把會話保存在服務端)
這裏以最多見的登錄案例講解cookie的使用過程:
1.首先用戶在客戶端瀏覽器向服務器發起登錄請求
2.登錄成功後,服務端會把登錄的用戶信息設置 cookie 中,返回給客戶端瀏覽器
3.客戶端瀏覽器接收到 cookie 請求後,會把 cookie 保存到本地(多是內存,也多是磁盤,看具體使用狀況而定)
4.之後再次訪問該 web 應用時,客戶端瀏覽器就會把本地的 cookie 帶上,這樣服務端就能根據 cookie 得到用戶信息了
session 是一種維持客戶端與服務器端會話的機制。可是與 cookie 把會話信息保存在客戶端本地不同,session 把會話保留在瀏覽器端。
咱們一樣以登錄案例爲例子講解 session 的使用過程:
1.首先用戶在客戶端瀏覽器發起登錄請求
2.登錄成功後,服務端會把用戶信息保存在服務端,並返回一個惟一的 session 標識給客戶端瀏覽器。
3.客戶端瀏覽器會把這個惟一的 session 標識保存在起來
4.之後再次訪問 web 應用時,客戶端瀏覽器會把這個惟一的 session 標識帶上,這樣服務端就能根據這個惟一標識找到用戶信息。
看到這裏可能會引發疑問:把惟一的 session 標識返回給客戶端瀏覽器,而後保存起來,之後訪問時帶上,這難道不是 cookie 嗎?
沒錯,session 只是一種會話機制,在許多 web 應用中,session 機制就是經過 cookie 來實現的。也就是說它只是使用了 cookie 的功能,並非使用 cookie 完成會話保存。與 cookie 在保存客戶端保存會話的機制相反,session 經過 cookie 的功能把會話信息保存到了服務端。
進一步地說,session 是一種維持服務端與客戶端之間會話的機制,它能夠有不一樣的實現。
以如今比較流行的小程序爲例,闡述一個 session 的實現方案:
1.首先用戶登錄後,須要把用戶登錄信息保存在服務端,這裏咱們能夠採用 redis。好比說給用戶生成一個 userToken,而後以 userId 做爲鍵,以 userToken 做爲值保存到 redis 中,並在返回時把 userToken 帶回給小程序端。
2.小程序端接收到 userToken 後把它緩存起來,之後每當訪問後端服務時就把 userToken 帶上。
3.在後續的服務中服務端只要拿着小程序端帶來的 userToken 和 redis 中的 userToken 進行比對,就能肯定用戶的登錄狀態了。
通過上面兩道題的闡述,這道題就很清晰了
1.cookie 是瀏覽器提供的一種緩存機制,它能夠用於維持客戶端與服務端之間的會話
2.session 指的是維持客戶端與服務端會話的一種機制,它能夠經過 cookie 實現,也能夠經過別的手段實現。
3.若是用 cookie 實現會話,那麼會話會保存在客戶端瀏覽器中
4.session 機制提供的會話是保存在服務端的。