http與https
基本概念
HTTP:是互聯網上應用最為廣泛的一種網絡協議,是一個客戶端和服務器端請求和應答的標准(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網絡傳輸減少。
HTTPS:是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
HTTPS協議的主要作用可以分為兩種:一種是建立一個信息安全通道,來保證數據傳輸的安全;另一種就是確認網站的真實性。
區別
HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,為了保證這些隱私數據能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。
HTTPS和HTTP的區別主要如下:
1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
HTTPS的工作原理
我們都知道HTTPS能夠加密信息,以免敏感信息被第三方獲取,所以很多銀行網站或電子郵箱等等安全級別較高的服務都會采用HTTPS協議。
客戶端在使用HTTPS方式與Web服務器通信時有以下幾個步驟,如圖所示。
1、客戶端發起 HTTPS 請求
這個沒什么好說的,就是用戶在瀏覽器里輸入一個 https 網址,然后連接到 server 的 443 端口。
2、服務端的配置
采用 HTTPS 協議的服務器必須要有一套數字證書,可以自己制作,也可以向組織申請,區別就是自己頒發的證書需要客戶端驗證通過,才可以繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面(startssl 就是個不錯的選擇,有 1 年的免費服務)。
這套證書其實就是一對公鑰和私鑰,如果對公鑰和私鑰不太理解,可以想象成一把鑰匙和一個鎖頭,只是全世界只有你一個人有這把鑰匙,你可以把鎖頭給別人,別人可以用這個鎖把重要的東西鎖起來,然后發給你,因為只有你一個人有這把鑰匙,所以只有你才能看到被這把鎖鎖起來的東西。
3、傳送證書
這個證書其實就是公鑰,只是包含了很多信息,如證書的頒發機構,過期時間等等。
4、客戶端解析證書
這部分工作是有客戶端的TLS來完成的,首先會驗證公鑰是否有效,比如頒發機構,過期時間等等,如果發現異常,則會彈出一個警告框,提示證書存在問題。
如果證書沒有問題,那么就生成一個隨機值,然后用證書對該隨機值進行加密,就好像上面說的,把隨機值用鎖頭鎖起來,這樣除非有鑰匙,不然看不到被鎖住的內容。
5、傳送加密信息
這部分傳送的是用證書加密后的隨機值,目的就是讓服務端得到這個隨機值,以后客戶端和服務端的通信就可以通過這個隨機值來進行加密解密了。
6、服務端解密信息
服務端用私鑰解密后,得到了客戶端傳過來的隨機值(私鑰),然后把內容通過該值進行對稱加密,所謂對稱加密就是,將信息和私鑰通過某種算法混合在一起,這樣除非知道私鑰,不然無法獲取內容,而正好客戶端和服務端都知道這個私鑰,所以只要加密算法夠彪悍,私鑰夠復雜,數據就夠安全。
7、傳輸加密后的信息
這部分信息是服務段用私鑰加密后的信息,可以在客戶端被還原。
8、客戶端解密信息
客戶端用之前生成的私鑰解密服務段傳過來的信息,於是獲取了解密后的內容,整個過程第三方即使監聽到了數據,也束手無策。
HTTPS的優點
盡管HTTPS並非絕對安全,掌握根證書的機構、掌握加密算法的組織同樣可以進行中間人形式的攻擊,但HTTPS仍是現行架構下最安全的解決方案,主要有以下幾個好處:
(1)使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
(2)HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程中不被竊取、改變,確保數據的完整性。
(3)HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本。
(4)谷歌曾在2014年8月份調整搜索引擎算法,並稱“比起同等HTTP網站,采用HTTPS加密的網站在搜索結果中的排名將會更高”。
HTTPS的缺點
雖然說HTTPS有很大的優勢,但其相對來說,還是存在不足之處的:
(1)HTTPS協議握手階段比較費時,會使頁面的加載時間延長近50%,增加10%到20%的耗電;
(2)HTTPS連接緩存不如HTTP高效,會增加數據開銷和功耗,甚至已有的安全措施也會因此而受到影響;
(3)SSL證書需要錢,功能越強大的證書費用越高,個人網站、小網站沒有必要一般不會用。
(4)SSL證書通常需要綁定IP,不能在同一IP上綁定多個域名,IPv4資源不可能支撐這個消耗。
(5)HTTPS協議的加密范圍也比較有限,在黑客攻擊、拒絕服務攻擊、服務器劫持等方面幾乎起不到什么作用。最關鍵的,SSL證書的信用鏈體系並不安全,特別是在某些國家可以控制CA根證書的情況下,中間人攻擊一樣可行。
HTTP Keep-Alive模式
什么是Keep-Alive模式?
我們知道HTTP協議采用“請求-應答”模式,當使用普通模式,即非KeepAlive模式時,每個請求/應答客戶和服務器都要新建一個連接,完成之后立即斷開連接(HTTP協議為無連接的協議);當使用Keep-Alive模式(又稱持久連接、連接重用)時,Keep-Alive功
能使客戶端到服務器端的連接持續有效,當出現對服務器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接。
http 1.0中默認是關閉的,需要在http頭加入"Connection: Keep-Alive",才能啟用Keep-Alive;http 1.1中默認啟用Keep-Alive,如果加入"Connection: close ",才關閉。目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的連接請求了,所以是否能完成一個完整的Keep-Alive連接就看服務器設置情況。
啟用Keep-Alive的優點
從上面的分析來看,啟用Keep-Alive模式肯定更高效,性能更高。因為避免了建立/釋放連接的開銷。然后翻譯下RFC 2616的總結
1、通過打開和關閉更少的TCP連接,CPU時間節省在路由器和主機(客戶端,服務器,代理,網關,隧道或緩存)中,而用於TCP協議控制塊的內存可以保存在主機中。
2、HTTP請求和響應可以在連接上通過管道傳遞。流水線允許客戶端發出多個請求而無需等待每個響應,從而可以更高效地使用單個TCP連接,而花費的時間卻少得多。
3、通過減少TCP開放引起的數據包數量,並允許TCP有足夠的時間確定網絡的擁塞狀態,可以減少網絡擁塞。
4、由於沒有時間花費在TCP連接打開握手上,因此減少了后續請求的延遲。
5、HTTP可以更優雅地發展,因為可以報告錯誤而不會關閉TCP連接。使用將來版本的HTTP的客戶端可能會樂觀地嘗試一項新功能,但是如果與舊服務器進行通信,則在報告錯誤后使用舊語義重試。
另外還指出:單用戶客戶端與任何服務器或代理之間的連接數不應該超過2個。一個代理與其它服務器或代碼之間應該使用超過2 * N的活躍並發連接。這是為了提高HTTP響應時間,避免擁塞(冗余的連接並不能代碼執行性能的提升)。
客戶端如何判斷服務端的數據已經發送完畢
未使用keep-alive-----這種情況現在已經非常少了
HTTP協議中客戶端發送一個小請求,服務器響應以所期望的信息(例如一個html文件或一副gif圖像)。服務器通常在發送回所請求的數據之后就關閉連接。這樣客戶端讀數據時會返回EOF(-1),就知道數據已經接收完全了。
使用keep-alive
Keep-Alive模式發送玩數據HTTP服務器不會自動斷開連接,所以不能再使用返回EOF(-1)來判斷。
1、使用消息首部字段Conent-Length
Conent-Length表示實體內容長度,客戶端(服務器)可以根據這個值來判斷數據是否接收完成。但是對於動態生成的內容來說,在內容創建完之前是不可知的,因此也就沒有這個字段。
2、使用消息首部字段Transfer-Encoding
當客戶端向服務器請求一個靜態頁面或者一張圖片時,服務器可以很清楚的知道內容大小,然后通過Content-length消息首部字段告訴客戶端需要接收多少數據。但是如果是動態頁面等時,服務器是不可能預先知道內容大小,這時就可以使用Transfer-
Encoding:chunk模式來傳輸數據了。即如果要一邊產生數據,一邊發給客戶端,服務器就需要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。
每一個非空的塊都以該塊包含數據的字節數(字節數以十六進制表示)開始,跟隨一個CRLF (回車及換行),然后是數據本身,最后塊CRLF結束。在一些實現中,塊大小和CRLF之間填充有白空格(0x20)。
最后一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最后一塊不再包含任何數據,但是可以發送可選的尾部,包括消息頭字段。
消息最后以CRLF結尾。
例如:
a、編碼的應答
HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 25 This is the data in the first chunk 1C and this is the second one 3 con 8 sequence 0
b、應答解釋
前兩個塊的數據中包含有顯式的\r\n字符。
"This is the data in the first chunk\r\n" (37 字符 => 十六進制: 0x25) "and this is the second one\r\n" (28 字符 => 十六進制: 0x1C) "con" (3 字符 => 十六進制: 0x03) "sequence" (8 字符 => 十六進制: 0x08)
應答需要以0長度的塊( "0\r\n\r\n".)結束。
c、解碼的數據
This is the data in the first chunk and this is the second one consequence
HTTP頭字段總結
常見的http頭如下:
- 1、 Accept:告訴WEB服務器自己接受什么介質類型,*/* 表示任何類型,type/* 表示該類型下的所有子類型,type/sub-type。
- 2、 Accept-Charset: 瀏覽器申明自己接收的字符集
Accept-Encoding: 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate)
Accept-Language:瀏覽器申明自己接收的語言
語言跟字符集的區別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等。 - 3、 Accept-Ranges:WEB服務器表明自己是否接受獲取其某個實體的一部分(比如文件的一部分)的請求。bytes:表示接受,none:表示不接受。
- 4、 Age:當代理服務器用自己緩存的實體去響應請求時,用該頭部表明該實體從產生到現在經過多長時間了。
- 5、 Authorization:當客戶端接收到來自WEB服務器的 WWW-Authenticate 響應時,用該頭部來回應自己的身份驗證信息給WEB服務器。
- 6、 Cache-Control:請求:no-cache(不要緩存的實體,要求現在從WEB服務器去取)
max-age:(只接受 Age 值小於 max-age 值,並且沒有過期的對象)
max-stale:(可以接受過去的對象,但是過期時間必須小於 max-stale 值)
min-fresh:(接受其新鮮生命期大於其當前 Age 跟 min-fresh 值之和的緩存對象)
響應:public(可以用 Cached 內容回應任何用戶)
private(只能用緩存內容回應先前請求該內容的那個用戶)
no-cache(可以緩存,但是只有在跟WEB服務器驗證了其有效后,才能返回給客戶端)
max-age:(本響應包含的對象的過期時間)
ALL: no-store(不允許緩存) - 7、 Connection:請求:close(告訴WEB服務器或者代理服務器,在完成本次請求的響應后,斷開連接,不要等待本次連接的后續請求了)。
keepalive(告訴WEB服務器或者代理服務器,在完成本次請求的響應后,保持連接,等待本次連接的后續請求)。
響應:close(連接已經關閉)。
keepalive(連接保持着,在等待本次連接的后續請求)。
Keep-Alive:如果瀏覽器請求保持連接,則該頭部表明希望 WEB 服務器保持連接多長時間(秒)。例如:Keep-Alive:300 - 8、 Content-Encoding:WEB服務器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應中的對象。例如:Content-Encoding:gzip
- 9、Content-Language:WEB 服務器告訴瀏覽器自己響應的對象的語言。
- 10、Content-Length: WEB 服務器告訴瀏覽器自己響應的對象的長度。例如:Content-Length: 26012
- 11、Content-Range: WEB 服務器表明該響應包含的部分對象為整個對象的哪個部分。例如:Content-Range: bytes 21010-47021/47022
- 12、Content-Type: WEB 服務器告訴瀏覽器自己響應的對象的類型。例如:Content-Type:application/xml
- 13、ETag:就是一個對象(比如URL)的標志值,就一個對象而言,比如一個 html 文件,如果被修改了,其 Etag 也會別修改,所以ETag 的作用跟 Last-Modified 的作用差不多,主要供 WEB 服務器判斷一個對象是否改變了。比如前一次請求某個 html 文件時,獲得了其 ETag,當這次又請求這個文件時,瀏覽器就會把先前獲得的 ETag 值發送給WEB 服務器,然后 WEB 服務器會把這個 ETag 跟該文件的當前 ETag 進行對比,然后就知道這個文件有沒有改變了。
- 14、 Expired:WEB服務器表明該實體將在什么時候過期,對於過期了的對象,只有在跟WEB服務器驗證了其有效性后,才能用來響應客戶請求。是 HTTP/1.0 的頭部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT
- 15、 Host:客戶端指定自己想訪問的WEB服務器的域名/IP 地址和端口號。例如:Host:rss.sina.com.cn
- 16、 If-Match:如果對象的 ETag 沒有改變,其實也就意味著對象沒有改變,才執行請求的動作。
- 17、 If-None-Match:如果對象的 ETag 改變了,其實也就意味著對象也改變了,才執行請求的動作。
- 18、 If-Modified-Since:如果請求的對象在該頭部指定的時間之后修改了,才執行請求的動作(比如返回對象),否則返回代碼304,告訴瀏覽器該對象沒有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
- 19、 If-Unmodified-Since:如果請求的對象在該頭部指定的時間之后沒修改過,才執行請求的動作(比如返回對象)。
- 20、 If-Range:瀏覽器告訴 WEB 服務器,如果我請求的對象沒有改變,就把我缺少的部分給我,如果對象改變了,就把整個對象給我。瀏覽器通過發送請求對象的 ETag 或者 自己所知道的最后修改時間給 WEB 服務器,讓其判斷對象是否改變了。總是跟 Range 頭部一起使用。
- 21、 Last-Modified:WEB 服務器認為對象的最后修改時間,比如文件的最后修改時間,動態頁面的最后產生時間等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
- 22、 Location:WEB 服務器告訴瀏覽器,試圖訪問的對象已經被移到別的位置了,到該頭部指定的位置去取。例如:Location:http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
- 23、 Pramga:主要使用 Pramga: no-cache,相當於 Cache-Control: no-cache。例如:Pragma:no-cache
- 24、 Proxy-Authenticate: 代理服務器響應瀏覽器,要求其提供代理身份驗證信息。Proxy-Authorization:瀏覽器響應代理服務器的身份驗證請求,提供自己的身份信息。
- 25、 Range:瀏覽器(比如 Flashget 多線程下載時)告訴 WEB 服務器自己想取對象的哪部分。例如:Range: bytes=1173546-
- 26、 Referer:瀏覽器向 WEB 服務器表明自己是從哪個 網頁/URL 獲得/點擊 當前請求中的網址/URL。例如:Referer:http://www.taobao.com/
- 27、 Server: WEB 服務器表明自己是什么軟件及版本等信息。例如:Server:Apache/2.0.61 (Unix)
- 28、 User-Agent: 瀏覽器表明自己的身份(是哪種瀏覽器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2、0、0、14
- 29、 Transfer-Encoding: WEB 服務器表明自己對本響應消息體(不是消息體里面的對象)作了怎樣的編碼,比如是否分塊(chunked)。例如:Transfer-Encoding: chunked
- 30、 Vary: WEB服務器用該頭部的內容告訴 Cache 服務器,在什么條件下才能用本響應所返回的對象響應后續的請求。假如源WEB服務器在接到第一個請求消息時,其響應消息的頭部為:Content-Encoding: gzip; Vary: Content-Encoding那么 Cache 服務器會分析后續請求消息的頭部,檢查其 Accept-Encoding,是否跟先前響應的 Vary 頭部值一致,即是否使用相同的內容編碼方法,這樣就可以防止 Cache 服務器用自己 Cache 里面壓縮后的實體響應給不具備解壓能力的瀏覽器。例如:Vary:Accept-Encoding
- 31、 Via: 列出從客戶端到 OCS 或者相反方向的響應經過了哪些代理服務器,他們用什么協議(和版本)發送的請求。當客戶端請求到達第一個代理服務器時,該服務器會在自己發出的請求里面添加 Via 頭部,並填上自己的相關信息,當下一個代理服務器收到第一個代理服務器的請求時,會在自己發出的請求里面復制前一個代理服務器的請求的Via 頭部,並把自己的相關信息加到后面,以此類推,當 OCS 收到最后一個代理服務器的請求時,檢查 Via 頭部,就知道該請求所經過的路由。例如:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)