前言
做軟件開發少不了與網絡打交道,在大學學習的計算機網絡知識僅能撐起一張補考試卷,工作中需要時就感覺四肢乏力、大腦空虛、萬劫不復,于是經過數次的翻查網上的資料,整理了一篇文章,以后自己忘掉后少走些彎路,多一點參考。
轉載需注明出處。
原文鏈接
1. HTTP
這是一個非常龐大的知識體,網上資料也鋪天蓋地鋪來,維基百科上說“HTTP(超文本傳輸協議)是互聯網上應用最為廣泛的一種網絡協議,設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法。通過HTTP或者HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,URI)來標識。HTTP是一個客戶端終端(用戶)和服務器端(網站)請求和應答的標準”。就像2000年Roy Fielding博士在他的論文中提出REST(Representational State Transfer)風格的軟件架構模式成為了Web API的標準,HTTP的發展是由Tim Berners-Lee在CERN發起由W3C和IETF制定的一套規范。蒂姆·伯納斯-李作為萬維網的發明者,在去年(2016年)獲得圖靈獎。
本篇只提供iOS開發相關知識點,如果深入挖掘,TCP/IP, UDP, OSI模型, 三次握手等知識點是挖掘不完的,就像一只爬蟲,爬到多少是個頭呢,所以說花至半開酒致微醉最佳,本章簡要總結請求格式和響應格式。
-
請求格式
發出的請求信息(message request)包括請求行,請求頭,空行,消息體。
-
請求行
請求行是請求消息的第一行,由三部分組成:分別是請求方法(GET/POST/DELETE/PUT/HEAD)、請求資源的URI路徑、HTTP的版本號。
GET / HTTP/1.1
-
請求頭
請求頭中的信息有和緩存相關的頭(Cache-Control,If-Modified-Since)、客戶端身份信息(User-Agent)等等。
Host: faichou.space Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/527.36 (KHTML, like Gecko) Chrome/57.0.2557.133 Safari/557.37 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4 Cookie: _ga=GA1.2.1965313251.1464240344; _gat=1 If-Modified-Since: Sun, 26 Mar 2017 14:29:48 GMT
?
-
空行
空的行。
-
消息體
請求體是客戶端發給服務端的請求數據,這部分數據并不是每個請求必須的。
-
-
響應格式
服務器接收處理完請求后返回一個HTTP響應消息給客戶端。HTTP響應消息的格式包括:狀態行、響應頭、空行、消息體。每部分內容占一行。
-
狀態行
狀態行位于相應消息的第一行,有HTTP協議版本號,狀態碼和狀態說明三部分構成。
HTTP/1.1 304 Not Modified
-
響應頭
響應頭是服務器傳遞給客戶端用于說明服務器的一些信息,以及將來繼續訪問該資源時的策略
Server: GitHub.com Date: Sat, 08 Apr 2017 07:15:29 GMT Last-Modified: Sun, 26 Mar 2017 14:29:48 GMT Access-Control-Allow-Origin: * Expires: Sat, 08 Apr 2017 07:25:29 GMT Cache-Control: max-age=600 X-GitHub-Request-Id: F804:6693:14F6B41:1C1E639:58E88E11
?
-
空行
空的行。
-
消息體
響應體是服務端返回給客戶端的HTML文本內容,或者其他格式的數據,比如:視頻流、圖片或者音頻數據。
-
2. Cookie
指某些網站為了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數據(通常經過加密)。— wikipedia
Cookie解決了HTTP連接無狀態的問題,是客戶端和服務器共同保持維護一些狀態數據。Cookie會被附加到http請求中,大多數瀏覽器都支持,無需用戶做額外操作,當然用戶可以手動刪除cookie。cookie的最大長度是4KB左右。使用cookie可以維持用戶的登錄態,只需要在cookie中添加一個token就可以。
客戶端請求信息,服務器響應返回,那么cookie被放在哪里呢?
通常是在響應頭中,被放置在Set-Cookie
字段中。這個字段瀏覽器會自動識別,并保存下來,下次請求時候會將cookie附加到請求頭中去。
舉個栗子
瀏覽器第一次給www.lxweimin.com
發送請求
GET / HTTP/1.1
Host: www.lxweimin.com
...
服務器返回帶有兩個Set-Cookie
字段的頭
HTTP/1.1 200 OK
Server: Tengine
Date: Sat, 08 Apr 2017 07:38:22 GMT
Set-Cookie: theme=light
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
...
服務器返回的信息除了包含首頁外,還有兩個重要的頭部信息Set-Cookie
,它指示瀏覽器保存下來。
Cookie的分類
Cookie總是保存在客戶端中,按在客戶端中的存儲位置,可分為內存Cookie和硬盤Cookie。
內存Cookie由瀏覽器維護,保存在內存中,瀏覽器關閉后就消失了,其存在時間是短暫的。硬盤Cookie保存在硬盤里,有一個過期時間,除非用戶手工清理或到了過期時間,硬盤Cookie不會被刪除,其存在時間是長期的。所以,按存在時間,可分為非持久Cookie和持久Cookie。
按照以上分類,服務器返回的兩個Cookie一個是內存Cookie(session cookie)另一個是硬盤Cookie(persistent cookie)。theme
指定了網頁的主題是亮色,它不包含Expires
或Max-Age
字段,故生存期短,瀏覽器關閉即死亡。sessionToken
是客戶端和服務器共同保持一個長登陸態的標志,它生存到Wed, 09 Jun 2021 10:18:14 GMT
,所以說它是一個persistent cookie。
接下來,瀏覽器繼續請求錢包頁面,其中請求頭中包含Cookie
字段,字段中有上次服務器發來的theme
和sessionToken
GET /wallet HTTP/1.1
Host: www.lxweimin.com
Cookie: theme=light; sessionToken=abc123
...
這樣服務器就知道這個用戶的這次請求是和前一次請求是相關的。服務器再收到請求后,返回錢包頁面,并且返回新的Set-Cookie
給用戶。這樣就可以指示用戶添加新cookie,更新cookie,或者刪除cookie了。
3. HTTPS
HTTPS,常稱為HTTP over TLS,HTTP over SSL或HTTP Secure,它是一個網絡安全傳輸協議。HTTPS經由HTTP通信,利用TSL/SSL來加密數據包。
在計算機網絡知識中,TSL/SSL介于應用層和TCP層之間。應用層數據不再直接傳遞給傳輸層,而是傳遞給TSL/SSL層,TSL/SSL層對從應用層收到的數據進行加密,并增加自己的TSL/SSL頭。
與HTTP的URL由http://
起始且默認使用端口80不同,HTTPS的URL由https://
起始且默認使用端口443。
HTTPS比HTTP多的就是安全,HTTP的數據是明文傳輸,在OSI模型中,任意一層捕獲到數據,既可以一覽無余,導致信息泄露,甚至可能被篡改,運營商流量劫持就是一個很好的例子。
在原理上是如何做到安全的呢?我們知道建立TCP連接需要三次握手,而TLS握手需要九次,而這個過程主要就是用來做非對稱加密。這里引申出來兩個重要概念,非對稱加密和對稱加密,理解它們有助于理解Charles抓HTTPS包。
-
對稱加密
對稱加密就是加解密使用同一個密鑰。客戶端和服務器通信一般會動態生成一個密鑰,所以密鑰如何安全傳遞就成了問題。非對稱加密正是為了解決這個問題,也就是密鑰交換(也叫密鑰協商)。
-
非對稱加密
瀏覽器和服務器每次新建會話時都使用非對稱密鑰交換算法協商出對稱密鑰,使用這些對稱密鑰完成應用數據的加解密和驗證,整個會話過程中的密鑰只在內存中生成和保存,而且每個會話的對稱密鑰都不相同(除非會話復用),中間者無法竊取。
服務器有一對公鑰和私鑰,公鑰用于加密,私鑰用于解密。密鑰交換過程:服務器的公鑰是公開的,私鑰是不公開的,只有服務器持有。瀏覽器先向服務器取得公鑰,然后用公鑰加密自己的私鑰連同自己私鑰加密的請求一并發送給服務器。服務器使用自己私鑰解密得到瀏覽器的私鑰,使用瀏覽器的私鑰解密請求。然后再用瀏覽器的私鑰加密response發送回服務器。
4. Charles
Charles 是在 Mac 下常用的網絡封包截取工具,在做移動開發時,我們為了調試與服務器端的網絡通訊協議,常常需要截取網絡封包來分析。
Charles 通過將自己設置成系統的網絡訪問代理服務器,使得所有的網絡訪問請求都通過它來完成,從而實現了網絡封包的截取和分析。
除了在做移動開發中調試端口外,Charles 也可以用于分析第三方應用的通訊協議。配合 Charles 的 SSL 功能,Charles 還可以分析 Https 協議。
傳統的中間人攻擊是無法攻擊HTTPS的,那么Charles是如何抓取的呢?
之前一直好奇,總認為Charles不能獲取服務器的秘鑰,是怎么抓取解密到包呢?簡直是魔法呀!
其實Charles也是個中間人,只不過它偽裝成了服務器,也打扮成了客戶端,是一個雙重身份。Charles使用時我們需要手動添加證書信任。這樣瀏覽器眼中的服務器就是Charles,而服務器眼中的客戶端也是Charles,從而實現了雙向數據解密。是不是很簡單呢。