主頁 >  其他 > 萬字長文,帶你徹底搞懂 HTTPS(文末附實戰)

萬字長文,帶你徹底搞懂 HTTPS(文末附實戰)

2023-04-20 07:31:11 其他

大家好,我是滿天星,歡迎來到我的技術角落,本期我將帶你一起來了解 HTTPS,

PS:本文同步發送至微信公眾號:技術角落,感興趣的同學可以查看:https://mp.weixin.qq.com/s/HbEhD93S7y3p8amlzS2sKw

前言

其實網上寫 HTTPS 的文章也不少了,但是不少文章都是從原理上泛泛而談,只講概念,沒有講原因,作為小白,看完還是會有一種似懂非懂的感覺,

本文嘗試從 HTTP 開始,一步一步深入到 HTTPS,告訴你 HTTPS 到底是什么、為什么需要 HTTPS、以及 HTTPS 到底是怎么做的,相信你在閱讀完本文后,一定會對 HTTPS 有深入的了解,

紙上得來終覺淺,除開原理部分外,本文還提供了 HTTP 和 HTTPS 的實戰教程,幫助你從 0 開始搭建一個 HTTPS 加密的 Web 服務器,如果按照實戰教程一步一步走下來,那么你將對 HTTPS 有更進一步的把握,

好了,廢話不多說,直接進入正題吧,

什么是 HTTPS ?一句話,HTTPS = HTTP + SSL, HTTPS 并不是一個全新的協議,而是在 HTTP 的基礎上,通過 SSL 增加了一層加密協議,從而大大增加了 HTTP 協議的安全性,

所以在正式了解 HTTPS 之前,我們需要先了解 HTTP,

1. HTTP

HTTP 全稱 超文本傳輸協議(HyperText Transfer Protocol),是一種廣泛用于互聯網中瀏覽器與服務器之間的應用層傳輸協議,簡單來說,瀏覽器向服務器發送 HTTP 請求,服務器向瀏覽器回傳 HTTP 回應,兩者之間通過這種方式進行“交流”,來使得我們的瀏覽器可以正常從服務器端獲取資料,并展示在用戶的電腦螢屏上,

以訪問 http://httpbin.org網址為例,一個典型的 HTTP 請求如下所示:

GET / HTTP/1.1
Accept: text/html,...
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Host: httpbin.org
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
  • GET 表示請求方法,常見的 HTTP 請求方法有 GET、POST、PUT、DELETE 等...
  • GET 后面的 /表示請求路徑,這里我們訪問的根路徑,所以顯示為 /,如果你訪問 httpbin.org/get的話,這里顯示的就是 /get
  • HTTP/1.1 表示使用的 HTTP 協議版本,現在常用的有 HTTP/1.1 和 HTTP/2,當然還有更先進的 HTTP/3,這里就不過多展開了
  • 下面的 9 行全部都是 HTTP header,每一個 header 包含 name 和 value,之間用冒號分隔開,

一個典型的 HTTP 回應如下所示

HTTP/1.1 200 OK
Date: Sat, 08 Apr 2023 16:28:43 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

body...
  • HTTP/1.1 指的協議版本,回應和請求的協議版本是一致的
  • 200 OK 代表回傳的回應碼,表示這個回應是符合預期的,另外還有非常常見的回傳碼 404 NOT FOUND ,大家應該或多或少聽說過,它表示服務器告訴你你訪問的這個資源不存在
  • 后面 7 行全部是 HTTP header,同樣每一個 header 包含 name 和 value,之間用冒號分隔開,
  • 最后是 HTTP Body,也就是回應體,即服務器回傳給你的內容主體,瀏覽器正是根據回應體來渲染頁面的

由于本文重點不在 HTTP,這里不再詳細介紹各個部分的作用,

如果你對 HTTP 還不太了解的話,我在本文附錄部分準備了一份 HTTP 實戰,建議你跟著實操一遍,了解下 HTTP 的基本結構,當然,這部分內容比較基礎,如果你已經對 HTTP 比較熟悉的話,這部分可以跳過了,

2. 為什么需要 HTTPS

上面簡單講了一下 HTTP,在正式講 HTTPS 之前,首先我們要搞清楚 HTTP 的缺點是什么,為什么需要 HTTPS,

我們知道,HTTP (除了最新的 HTTP/3 外),傳輸層是基于 TCP 協議的,TCP 建立連接時,有三次握手,三次握手完畢之后,TCP 連接就順利建立了,接下來兩端將會傳輸資料,

對于普通的 HTTP 協議,在建立完 TCP 連接之后,就直接開始傳輸資料了,這時候資料是明文傳輸的,這也是 HTTP 最不安全的地方,

明文傳輸是什么概念呢?我們知道,瀏覽器和服務器之間,是存在很長一條路線的,你在家里通過瀏覽器訪問網頁的時候,資料會從你的電腦,傳到你家里的路由器,再到光貓,到運營商,到互聯網....直到最后才到服務器,在明文傳輸下,理論上來講,瀏覽器和服務器之間的任一節點,包括你家里的路由器、包括你購買寬帶/流量的運營商,都可以“竊聽”你們的資料,甚至還可以修改資料,

聽起來不夠直觀?打個比方,近代時期,戰場上打仗時,部隊之間會通過電臺進行交流,如果通過明文進行交流,那么非常危險,敵軍可以打開電臺進行竊聽,偷取你的軍事情報,這樣的事也屢見不鮮了...那么他們是如何解決這個問題的呢?兩個部隊之間提前約定一個加密的方案,在傳資料之前,先把它進行加密再傳輸,另一端收到資料之后,按照事先約定的方案進行解密,然后讀取就可以了,這樣即使敵軍開始竊聽,也只能聽到加密后的情報,如果無法對其破解的話,得不到任何有效資訊,

沒錯,這就是 HTTPS 的思想,瀏覽器在發送 HTTP 請求之前,先通過某種方式對其進行加密,然后再進行傳輸,服務器端收到資料之后,對其解密,讀取真實內容,生成 HTTP 回應,同樣對回應進行加密,然后傳回給瀏覽器,瀏覽器收到資料之后,對其進行解密,得到真正的 HTTP 回應,這樣就可以保證資料在傳輸程序中的安全性,無論是路由器還是運營商,都沒有辦法“竊聽”你們的資料了,

說到這里,想必你已經知道 HTTPS 的一大作用了,它可以保證資料在互聯網上傳輸的安全性,避免中間節點進行竊聽和修改,

當然,聰明的你還可能會想到一些問題,例如:

  1. 戰場上軍隊之間是提前約定好加密方案的,但是咱們任意一個瀏覽器都可以隨時訪問網頁,沒有辦法提前約定加密方案呀,那是怎么做到的呢?
  2. 戰場上經常出現敵軍對另一方部隊之間的電臺加密進行破解的事情,破解完成之后,還是能夠竊聽到資料,那 HTTPS 的這個加密方案到底安全嗎,會被破解嗎?

別急,這些問題,你都可以在本文中得到答案,

3. HTTP + SSL = HTTPS !

上面提到了對 HTTP 進行加密的思想,在 HTTPS 的具體實作中,這個加密方案即是大名鼎鼎的 SSL(Secure Sockets Layer),

定義:SSL(Secure Sockets Layer)是一種安全協議,用于在互聯網上保護資料的傳輸安全,它作業在傳輸層,主要功能是通過加密技術,保護不同計算機之間的資料傳輸程序,防止敏感資料被黑客竊取和篡改,SSL 協議可以用于保護網站的用戶登錄、信用卡支付、網上銀行等敏感資訊的傳輸,以及企業之間的機密資料的傳輸,SSL 協議目前已經被繼承為 TLS(Transport Layer Security),是一種安全性更高的傳輸層協議,所以,下面我將統一以 TLS 為名稱進行講解,

首先,劃重點,TLS 中有 Transport Layer,顧名思義,它一定是作業在傳輸層了,上面提到過,HTTP 是應用層協議,傳輸層和應用層的概念,想必大家應該知道吧,計算機網路的事實標準中,自頂向下可以分為五層:應用層、傳輸層、網路層、鏈路層、物理層...這是《計算機網路》的基礎,這里不過多展開,不熟悉的同學,要回去重修一下課程了,

我們知道,TCP 協議里有三次握手,三次握手成功后連接才算建立,接下來才會真正開始傳輸資料,傳統的 HTTP 協議中,三次握手成功之后,就會直接開始明文傳輸 HTTP 資料了,

那么 TLS 是什么時候開始發揮作用的呢?答案很簡單,在三次握手之后,傳輸資料之前,

也就是說,在 TCP 協議中加入 TLS 之后,三次握手成功之后就不會再立刻開始傳輸資料了,而是緊接著開始 TLS 的建立程序,也被稱為 TLS 握手,

TLS 握手是干嘛呢?或者說為什么需要 TLS 握手呢?上面提到,在戰場上,兩個部隊之間會提前約定好加密的方案,例如面對面用紙互相寫下加密方案,然后在一段時間之內的電臺通信統一用這個加密方案,這樣能一定程度上保證電臺通信的安全性,但是 TLS 中我們并沒有這樣一個“面對面”的機會,咱們總不可能在訪問網頁之前,人肉跑到服務器的維護者那邊去跟他約定加密方案吧,出于這個目的,TLS 握手便出現了,所以我們可以說,TLS 握手的目的是給通信雙方約定一個安全的加密方案(可以理解為商量一個只有雙方知道的加密密鑰),

知道了 TLS 握手的目的,接下來我們需要知道它具體是怎么做的,首先,我們肯定不能直接明文傳輸加密方案(密鑰),不然這個密鑰在傳輸程序中就直接被第三方獲取了,那么加密將沒有任何意義,也就是說,TLS 握手需要做到:通信雙方可以約定一個共同的加密方案(密鑰),并且這個約定的程序(即 TLS 握手程序),即使被任何第三方竊聽到,也無法決議出這個加密方案(密鑰)

是不是聽起來很神奇,那到底是怎么做到的呢?這就不得不提到密碼學中非常經典的兩個概念:對稱加密和非對稱加密,

4. 對稱加密,非對稱加密

·

對稱加密是 TLS 握手成功后,通信雙方之間采用的資料加密方案,現在的主要問題是:通信雙方如何安全的商量好這個對稱密鑰,防止密鑰被其他人竊取?

這時就需要輪到非對稱加密出場了,什么是非對稱加密呢?與對稱加密不同,非對稱加密方案中,用戶手握兩把密鑰,一把稱為公鑰,一把稱為私鑰,其中公/私鑰都可以用來加密/解密資料,但是:用公鑰加密后的資料,只有用私鑰才能將其解開;用私鑰加密后的資料,只有用公鑰才能將其解開!

這里只介紹了非對稱加密的特點,并沒有介紹其原理,因為這屬于密碼學的范疇了,展開來講又是一篇文章,簡單說說其思想吧,目前流行的非對稱加密演算法 RSA 基于的原理其實就一句話:我們目前還沒有很好的辦法對一個很大的數做因式分解,例如你在心里默默想一個很大的質數 p 和 質數 q,算出其乘積 n,那么向外公開 n 的話,外部人員是很難找出 p 和 q 的(只能暴力嘗試,而當這樣的數夠大夠多的時候,以現在的計算機算力也需要幾百上千年的時間才能破解了),對密碼學感興趣的同學,可自行進一步了解,

有了非對稱加密,事情就變得有意思起來了,見下圖,服務器端用非對稱加密方案生成一對公/私鑰,私鑰掌握在自己手里,誰也不告訴;在 TLS 握手的程序中,服務器將自己的公鑰交給瀏覽器端,瀏覽器端在心里默默想出一個對稱加密的密鑰后,將這個密鑰用服務器端的公鑰進行加密,然后再傳回給瀏覽器端;瀏覽器端收到這個資料之后,用自己的私鑰將其進行解密,就能夠得到剛才瀏覽器心里默念的那個對稱密鑰了,這樣這個問題就完美的解決了,兩邊可以心有靈犀的拿到這個對稱密鑰,而不用擔心被任何第三方竊取到了,

這就是 TLS 握手的程序嗎?不,當然沒這么簡單了,我們還沒有考慮一個非常巧妙的攻擊手段:中間人攻擊,

5. 中間人攻擊

具體什么是中間人攻擊呢?看下面這張圖

假設現在我們從電腦上訪問百度,如果有一個中間人在我的路由器端,或者運營商端,或者任何一個中間節點上截取了我的請求,剛不是提到服務器端需要回傳給我們公鑰嗎,中間人他自己也生成一套公/私鑰,然后將自己的公鑰回傳給我,這樣我就與中間人之間建立了一條我以為“安全”的連接了,此時我以為我連接的是百度服務器,其實我連接的是中間人...那么此時中間人可以做任何事情了,如果他人品比較好的話,他可以默默當一個代理,我要訪問百度,他就去幫我訪問百度,然后把結果回傳給我,勤勤懇懇做一個“中間商”,當然,我們知道做這種攻擊的人人品往往不會太好,所以他們可以做更壞的事情,例如偽造一個銀行網頁回傳給我,讓我填寫賬號和密碼,這樣的話...后果就不堪設想了,

那么如何防止中間人攻擊呢?其中的核心就是:我們需要保證我們訪問的就是目標服務器,例如,當我們訪問百度時,我們需要確保在 TLS 握手時,給我們公鑰的人就是百度,而不是任何其他人,

那么這個應該如何去保證呢?這就不得不提到接下來的幾個概念了,數字證書,以及證書權威機構(Certificate Authority,簡稱 CA),

6. 數字證書、CA

數字證書是由證書權威機構(CA)頒發的一個用于證明身份的證書,當然其中還包含了該用戶的公鑰等資訊,例如還是以百度為例,假設百度需要給 www.baidu.com這個域名申請一個數字證書,他需要在生成公鑰/私鑰后,將自身的資訊(包括域名、公司名稱、公鑰資訊等)發給某個證書權威機構(CA),讓 CA 給自己頒發一個數字證書,CA 需要驗證百度的真實身份,并且他確實擁有 www.baidu.com這個域名,一切都驗證通過后,CA 才會給百度頒發這么一個數字證書,那么之后,不管是誰用瀏覽器訪問 www.baidu.com的時候,百度都會將剛才那個 CA 頒發的數字證書發送給用戶,既可以用來自證身份,同時還順便告訴了用戶自己的公鑰,

到這里你可能還會有幾個疑問:

  1. 數字證書如何保證不能偽造呢,難道中間人不能偽造一個數字證書發送給用戶嗎?
  2. 即使數字證書不能被偽造,從概念上看他是公開的,難道中間人不能直接把這個證書頒發給用戶嗎?

下面會一一回答這幾個問題,正式回答之前,先來看看數字證書里究竟有哪些內容,

既然上面提到百度,我們就以百度為例,我們使用瀏覽器訪問百度,可以在地址欄左邊看到一個小鎖,點擊后,就可以查看百度的數字證書

圖中可以看到該證書的一些基本資訊:

  • 頒發物件:這個證書是頒發給百度的,并且只對域名 (www.)baidu.com 有效
  • 頒發者:這個證書是由 GlobalSign 頒發的,(GlobalSign是一家全球知名的證書權威機構)
  • 有效期:這個證書的有效期是從 2022 年 7 月到 2023 年 8 月,(一旦過期,證書將不被信任)
  • 指紋:指紋是整張證書經過哈希計算后得到的特征值,主要與后面會提到的簽名一起作業,起到防篡改的作用

當然,一張數字證書的內容遠遠不止于此,例如還包含了服務器的公鑰,可以在“詳細資訊”中進行查看,

下面我們在證書詳細資訊中點擊“匯出”,將證書匯出為 Base64 編碼的單一證書,然后使用 openssl 對其進行決議和查看

$ openssl x509 -noout -text -in baidu.com.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:17:ce:86:ef:82:ec:69:21:cc:6f:68
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign RSA OV SSL CA 2018
        Validity
            Not Before: Jul  5 05:16:02 2022 GMT
            Not After : Aug  6 05:16:01 2023 GMT
        Subject: C=CN, ST=beijing, L=beijing, OU=service operation department, O=Beijing Baidu Netcom Science Technology Co., Ltd, CN=baidu.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:aa:2f:cc:41:8d:25:ae:83:e9:f4:27:c4:00:b3:
                    39:6f:0e:98:2a:55:7d:07:e5:80:49:82:fa:d3:d3:
                    85:98:b5:df:7b:6f:bb:02:dd:ed:78:e4:0c:07:2b:
                    9e:1e:86:4b:f6:6a:86:58:d7:57:6f:21:59:11:d8:
                    6f:96:6e:d2:de:36:28:f6:b4:e3:ce:95:32:29:00:
                    c1:65:8e:69:b0:00:fe:52:37:f4:88:3f:8b:6d:0f:
                    bb:f0:ec:c5:c0:31:ef:ad:b5:0c:06:66:ad:be:dc:
                    43:13:c4:66:b0:5d:cf:56:53:e2:d1:96:82:1c:06:
                    bb:9b:5f:ed:60:8d:d2:ed:f3:d2:50:ee:bb:cd:b2:
                    36:97:c8:ce:7b:d2:4b:b7:5c:b4:88:ca:37:6e:8b:
                    ce:f9:96:fd:b4:f5:47:b5:20:77:bb:fc:a8:9d:81:
                    b2:6c:f8:c7:09:6a:dd:22:6e:83:3f:a7:53:df:f1:
                    da:2f:29:6b:22:c3:e9:1d:65:e8:c5:a0:ba:13:4e:
                    16:3f:03:93:f0:a5:59:8a:1a:80:e8:27:7d:49:23:
                    df:d1:f9:4b:97:b7:01:c4:19:f5:f1:c5:ff:91:33:
                    d0:a1:74:c6:ee:d4:cf:f6:38:0c:ed:bd:5e:aa:44:
                    fb:88:f7:7b:99:70:76:34:55:7e:55:d2:0f:9e:bf:
                    94:93
                    
  	... (中間省略)
   
    Signature Algorithm: sha256WithRSAEncryption
         63:21:07:23:47:06:eb:b3:7c:77:6c:df:bc:55:12:b9:f1:5e:
         6a:04:60:16:be:d0:0b:18:9c:94:0c:a8:82:08:25:0d:26:fb:
         dd:cb:fc:8c:27:d9:0c:fa:4a:b6:31:b6:67:f0:26:2c:0d:96:
         96:39:65:3f:d9:a1:ee:de:9c:10:4d:54:e1:c8:d6:a9:0e:77:
         db:00:e2:37:e3:3f:b4:9c:31:4f:ac:74:d3:22:12:53:36:d0:
         ef:18:07:2d:8e:d0:e6:91:b2:6c:4a:5e:39:53:14:58:4e:d1:
         50:04:c9:83:7e:0d:7b:15:96:87:11:d7:5d:4a:17:ac:aa:9f:
         84:e3:a8:24:9d:d6:17:77:26:8c:9f:7a:7b:18:da:39:2f:77:
         f7:2b:c7:23:b8:97:6f:c3:d1:72:4c:7e:fc:c6:0d:cc:73:38:
         19:81:fb:e7:c1:7a:e8:b9:1d:3a:05:dc:36:04:9b:f1:f0:e1:
         a6:47:a0:30:4f:55:90:6c:da:cf:9e:b2:76:12:11:a1:5c:b6:
         61:8d:15:a4:68:65:9a:57:2f:7a:6e:a3:1f:f5:b4:92:5a:3c:
         df:71:0a:cd:57:d4:d0:15:36:7e:ba:d5:03:25:27:45:b4:60:
         cd:2e:02:c1:0f:0a:e7:41:6f:58:69:20:9e:ad:47:52:1a:b5:
         e6:e5:8d:1d

可以看到,除了上面 Chrome 里顯示的一些基本資訊外,證書里還包含了幾個重要資訊:

  • 服務器端的公鑰,即上面 RSA Public-Key 下面的那一長串數字,就是百度的公鑰了,
  • 簽名,證明數字證書有效的關鍵資訊,如果把數字證書類比成一張合同的話,我們知道合同需要老板簽字才算有效,同樣,數字證書是需要 CA 簽名才算有效的,這里的一長串字符就是 CA 對該證書的“簽名”了,

我們知道合同上的簽名是靠筆跡鑒定來確認真偽的,很明顯這一長串字符里沒有筆跡,那它是如何保證該簽名是 CA 頒發的,而不是被其他人偽造的呢?

上面我們提到,每一張數字證書有一個指紋,是將整張證書經過哈希運算后得到的特征值,CA 作為權威機構,其本身也是有一對公鑰/私鑰的,它在頒發數字證書的時候,會用自己的私鑰對證書的指紋進行加密,生成的這段加密資料,就是該證書的簽名了!那么我們瀏覽器是如何驗證證書的真偽呢?我們只需要使用 CA 的公鑰對簽名進行解密,看看得到的值是不是跟證書的指紋是一樣的,這樣就 OK 了,只要是一樣,說明這個證書一定是 CA 頒發的,

那么,又有問題來了:我們瀏覽器是從哪里拿到 CA 的公鑰呢?總不能還是通過網路傳輸吧,這樣就有“套娃”的中間人攻擊風險了,所以啊,我們的瀏覽器或作業系統已經內置了世界權威的 CA 的數字證書(證書里就包含了其公鑰)了,點擊瀏覽器的 設定 -> 隱私設定和安全性 -> 安全 -> 管理設備證書,可以查看當前系統內置的所有 CA 證書,

上圖是我的電腦中內置的 CA 證書,剛剛提到了百度的數字證書是由 GlobalSign 頒發的,這里也可以驗證,GlobalSign 是被我們的作業系統所信任的 CA,并且我們已經將它的證書內置在作業系統中了,因此現在我們可以認定說,這個證書是值得信任的,與我們建立連接的就是百度,不是別人,

你可能會想,如果中間人將百度真實的數字證書回傳給我呢?中間人是沒有百度的私鑰的,所以當我們提取出證書中的公鑰,并對心里想的密鑰進行加密后,中間人是解不開這個密鑰的,所以中間人無論如何也無法與我們建立連接,

好了,數字證書的內容已經全部講述完畢了,最后回過頭來復習下前面提到的兩個問題:

  1. 數字證書如何保證自身不會被偽造?

數字證書中有一段簽名,該簽名是 CA 使用其私鑰對證書指紋進行加密后得到的值,我們瀏覽器使用 CA 的公鑰對該簽名進行解密后,與該證書的指紋進行對比,就可以知道證書是否被篡改或者偽造了,

當然,這里要多提一嘴,我們作為客戶端,需要保證自己的電腦里保存的都是值得信任的 CA 根證書,因為信任某 CA 就代表信任了該 CA 頒發的所有數字證書,如果有人/軟體想在你的電腦里安裝來歷不明的 CA 證書,那你就要保持警惕了...

  1. 如果中間人直接把真實的數字證書回傳給我,它能夠成功與我建立連接嗎?

答案是不行的,這個問題其實比較簡單,剛剛提到,服務器端除了公鑰外,自身還保存有一份私鑰的,而中間人是拿不到這個私鑰的,因為它被服務器雪藏起來,不會發送到互聯網中的...那么如果中間人用服務器的證書回傳給用戶,用戶采用服務器的公鑰對自身默念出來的對稱密鑰進行加密后,回傳給中間人的時候,中間人就一臉懵逼了,因為這個密鑰它解不開呀,它沒有私鑰的,所以這個問題就完美解決了,

7. TLS 握手具體程序

最后,我們再完完整整講一下 TLS 握手的具體流程,

上圖來自 www.ssl.com,展示了整個握手流程,我用大白話解釋一下:

  1. 客戶端向服務器發送 Client Hello 資訊,告知自己想要建立一條 TLS 連接,并告知自己支持的加密演算法,
  2. 服務器向客戶端發送一個 Server Hello 的回應,并選擇一個加密演算法,同時給客戶端發送自己的數字證書(包含服務器的公鑰),
  3. 客戶端驗證服務器發來的數字證書,驗證通過后,在心里默默想出一個 pre-master 密鑰(預主密鑰),然后使用服務器的公鑰,將預主密鑰進行加密后,發送給服務器,
  4. 服務器用自己的私鑰進行解密,得到預主密鑰,
  5. 客戶端和服務器都通過預主密鑰,進行相同的計算后,得到后續通信時使用的對稱加密密鑰,稱為 shared secret,
  6. 客戶端和服務器端都分別用生成的 shared-secret 加密一段報文后,發送給對方,以驗證對方能夠成功收到資訊并解密,
  7. 然后 TLS 就建立成功了,接下來雙方都用這個 shared-secret 進行加密通信,

總結一下,HTTPS 的加密程序中其實既用到了非對稱加密也用到了對稱加密,其中握手程序使用的是非對稱加密,主要目的是雙方可以安全的協商一個統一的密鑰,而真正的資料傳輸程序則使用的是對稱加密,正是使用剛才商量的這個密鑰,

你可能會問,為什么不全程使用非對稱加密呢?因為對稱加密效率更高,尤其是在大量資料的時候,對稱加密比非對稱加密整整快幾個數量級,所以真正資料傳輸的程序選用了對稱加密,

到這里,HTTPS 的原理就已經全部介紹完畢了,大家如果還有什么疑問,歡迎在評論區留言討論,

8. 總結

最后,我們總結一下,HTTPS 解決了兩個問題:

  1. 資料傳輸程序中的安全問題,因為它對資料進行了加密,只有瀏覽器和服務器可以對其進行解密,
  2. 瀏覽器對服務器的信任問題,數字證書以及其中的數字簽名,保證了我們訪問的就是我們想要訪問的服務器,不可能被釣魚網站欺騙,也不可能被中間人攻擊所欺騙,

當然,保證以上安全的前提是我們的電腦本身沒有被攻破,如果你的電腦被黑客攻擊,裝上了來歷不明的根證書,那么 HTTPS 也不能保障你的安全了,

附錄一:HTTP 實戰

這里的實操部分針對不太熟悉 HTTP 的同學,熟悉的同學請直接跳過...

在瀏覽器(建議 Chrome)中訪問httpbin.org,并使用開發者工具進行觀察

點擊 Request Headers 后面的 View source,可以看到原始的 HTTP 請求報文,摘抄如下

GET / HTTP/1.1
Accept: text/html,...
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Host: httpbin.org
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36

其中:

  • GET 表示請求方法,常見的 HTTP 請求方法有 GET、POST、PUT、DELETE 等...
  • GET 后面的 /表示請求路徑,這里我們訪問的根路徑,所以顯示為 /,如果你訪問 httpbin.org/get的話,這里顯示的就是 /get
  • HTTP/1.1 表示使用的 HTTP 協議版本,現在常用的有 HTTP/1.1 和 HTTP/2,當然還有更先進的 HTTP/3,這里就不過多展開了
  • 下面的 9 行全部都是 HTTP header,每一個 header 包含 name 和 value,之間用冒號分隔開,

當然,點擊 Response Headers 后面的 view source,你就可以看到服務器回傳給你的 HTTP 回應頭是怎么樣的了

HTTP/1.1 200 OK
Date: Sat, 08 Apr 2023 16:28:43 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

body...
  • HTTP/1.1 指的協議版本,回應和請求的版本肯定是一樣的了
  • 200 OK 代表回傳的回應碼,表示這個回應是 OK 的,另外還有非常常見的回傳碼 404 NOT FOUND ,表示服務器告訴你你訪問的這個資源不存在...
  • 后面 7 行全部是 HTTP header,同樣每一個 header 包含 name 和 value,之間用冒號分隔開,
  • 最后是 HTTP Body,也就是回應體,在 Response Header 里是看不到了,不過點擊上面 Tab 頁的 Response 后,就可以看到完整的回應體了,

由于本篇文章的重點不在 HTTP,這里就不再過多展開,非常建議大家平時使用瀏覽器訪問網頁的時候,有事沒事多打開下上面的開發者工具,看看 HTTP 到底是怎么作業的,說不定,還能找到一份作業呢...

(訪問百度時,開發者工具中的小彩蛋)

當然,作為程式員,還是希望有更“極客”的方式來了解 HTTP 協議,這時候就要用到 curl命令了

終端里輸入 curl -v httpbin.org,可以看到整個 HTTP 互動的流程

附錄二:數字證書實戰

這部分實戰教程將帶你體驗 HTTPS 的全流程,從證書生成、到 HTTPS 服務器建設、到最后的瀏覽器訪問,教程將從以下三個方面進行:

  1. 首先利用 openssl工具,模擬一個證書權威機構(CA),生成 CA 證書以及密鑰,
  2. 然后利用 openssl工具,模擬 techcorner.cn網站的維護者,向上面的 CA 機構申請一個數字證書
  3. 使用 Nginx 搭建自己的 HTTPS 服務器,并使用上面生成的服務器證書,
  4. 使用瀏覽器訪問自己搭建的 HTTPS 服務器,體會全加密流程,

值得一提的是,網上也有不少利用 openssl 生成證書的教程,但是它們質量參差不齊,絕大多數都無法生成一個瀏覽器識別的、能夠真正用在生產環境中的證書,而本教程是我查閱官方檔案、并且親自試驗過的教程,絕對有效,

實戰前,你需要準備:

  • Mac / Linux 服務器
  • 安裝 openssl 工具、以及 Nginx ,

1. 生成 CA 證書

我們知道服務器拿到的數字證書都是從 CA 那邊頒發的,所以首先我們需要模擬出一個 CA 機構,即生成 CA 證書以及密鑰,

首先生成 CA 私鑰(公鑰可以從私鑰中提取而來)

# 生成 CA 私鑰 
openssl genrsa -out ca.key 2048

然后生成證書簽發申請檔案

# 生成證書簽發申請檔案(.csr)
openssl req -new -key ca.key -out ca.csr -subj '/C=CN/ST=Zhejiang/L=Hangzhou/O=Tech_Corner/CN=ROOTCA'

-subj 后面的引數代表了生成證書的基本資訊,包括國家、省份、城市、公司名稱等,CN=ROOTCA,代表是準備申請一個根證書,

然后根據上面生成的私鑰和證書申請檔案,自簽一個根證書

# 自簽一個根證書
openssl x509 -req -days 365 -sha256 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.cer

總結一下,以上命令,一共生成了三個與 CA 有關的檔案:

  • ca.key:CA 私鑰
  • ca.csr:CA 為自己簽發證書的請求,(該檔案的作用是生成 CA 證書,生成之后不會再用到)
  • ca.cer:CA 為自己簽發的證書

可以用 openssl 命令,查看下申請的證書資訊

$ openssl x509 -in ca.cer -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            92:63:8f:e3:23:97:e1:c6
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Zhejiang, L=Hangzhou, O=Tech_Corner, CN=ROOTCA
        Validity
            Not Before: Apr 11 15:39:56 2023 GMT
            Not After : Apr 10 15:39:56 2024 GMT
        Subject: C=CN, ST=Zhejiang, L=Hangzhou, O=Tech_Corner, CN=ROOTCA
        ... 以下省略

2. 生成服務器證書

接下來,我們模擬網站 techcorner.cn的維護者,想要為自己的網站申請一個數字證書,所以我們需要向上面模擬的 CA 來申請證書,

同樣,我們首先生成一個自己的私鑰 ,

openssl genrsa -out server.key 2048

然后,生成一個證書簽發申請檔案

openssl req -new -key server.key -out server.csr -subj '/C=CN/ST=Zhejiang/L=Hangzhou/O=Tech_Corner/CN=techcorner.cn'

注意,這里 -subj中有一個很重要的引數是 CN=techcorner.cn,它代表我們生成的證書,只簽發給這個域名,換句話說,其他的域名如果使用這個證書,會被瀏覽器判斷為無效,

以上證書簽發申請檔案(server.csr) 發送給 CA 后,CA 會對其做一些驗證,例如驗證申請者本身是不是符合資質,是不是確實擁有這個域名,等等,都確認完畢后,CA 才會決定給用戶頒發這個證書,(CA 必須維護自己的權威性,隨便頒發證書的 CA 將被世界所拋棄,已經有這樣的先例了)

CA 為其頒發證書的命令,可模擬如下

openssl x509 -req -extfile <(printf "subjectAltName=DNS:techcorner.cn,DNS:www.techcorner.cn") -days 365 -in server.csr -CA ca.cer -CAkey ca.key -CAcreateserial -out server.cer

其中比較有意思的是 -extfile后面填寫的 subjectAltName=...這一串,這其實是 X509 V3 證書里面的欄位,對于普通的 TLS 加密,他可能不是必須的,但是對于 HTTPS,尤其是瀏覽器來說,它會額外對這個欄位進行校驗,確保其中存在當前訪問的域名,否則即使 CN滿足,瀏覽器同樣不會信任這個證書!(網上很多教程都沒有注意到這個地方,導致最后生成的證書不可用)

得到的服務器證書為 server.cer,同樣可以使用 openssl 查看證書

$ openssl x509 -in server.cer -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            80:56:02:4d:21:ff:5e:60
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=CN, ST=Zhejiang, L=Hangzhou, O=Tech_Corner, CN=ROOTCA
        Validity
            Not Before: Apr 11 15:52:10 2023 GMT
            Not After : Apr 10 15:52:10 2024 GMT
        Subject: C=CN, ST=Zhejiang, L=Hangzhou, O=Tech_Corner, CN=techcorner.cn
...以下省略

上面可以看到該證書的基本資訊(Subject),以及頒發者資訊(Issuer)等,

3. 啟動 Nginx,并使用上面生成的服務器證書

編輯 nginx.conf,添加 HTTPS 埠的監聽

server {
   listen       443 ssl;
   server_name  techcorner.cn;

   ssl_certificate      /path/to/server.cer;
   ssl_certificate_key  /path/to/server.key;

   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;

   ssl_ciphers  HIGH:!aNULL:!MD5;
   ssl_prefer_server_ciphers  on;

   location / {
       root   html;
       index  index.html index.htm;
   }
}
  • ssl_certificate的值修改為上一步生成的 server.cer 的絕對地址
  • ssl_certificate_key的值修改為上一步生成的 server.key 的絕對地址

然后啟動 Nginx,

啟動完畢后后,通過瀏覽器訪問 https://localhost:443訪問 Nginx

可以看到瀏覽器給出了不安全的警告,這是符合預期的,因為我們使用的證書是自己使用 openssl 簽發的,CA 機構也是自己模擬的,并不在電腦的信任串列中,

如果想要正常訪問,可以在系統的根證書串列中,將我們自己模擬的 CA 證書添加進去(Mac 系統中,將根證書 ca.cer拖入鑰匙串訪問的 系統 中即可,并對其進行 “始終信任”),

這個 CA 證書是我們自己生成的,只要我們自己不泄漏其私鑰,那么將是安全的

使用瀏覽器重新訪問 https://localhost:443,得到如下結果

可以發現仍然是 不安全 的狀態,不過這時錯誤代碼已經變了,剛才是 ERR_CERT_AUTHORITY_INVALID,意思是頒發證書的 CA 機構無效,

而現在錯誤變成了 ERR_CERT_COMMON_NAME_INVALID,這是什么意思呢?它其實是說證書的 CN 和我們訪問的地址不匹配,怎么理解呢?還記得我們創建該證書的時候,里面包含了 CN=techcorner.cn,意思是這個證書只能被 techcorner.cn這個域名使用,現在我們訪問的是 localhost,顯然他們是不匹配的,因此證書無效,

雖然我們沒有購買該域名的使用權限,但是可以通過在本地修改 hosts 的方式,強行將 techcorner.cn決議為本機地址 127.0.0.1

具體方式為,修改本機的 /etc/hosts檔案,在檔案末尾增加一行

127.0.0.1 techcorner.cn

添加完畢后,再次使用瀏覽器訪問 https://techcorner.cn

可以發現,Chrome 提示連接是安全的,證書是有效的

Perfect,恭喜你,到這里,實戰部分就結束了,你已經成功體驗了 HTTPS 的全部內容,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/550550.html

標籤:其他

上一篇:做個清醒的程式員之擁抱AI

下一篇:稀疏陣列

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more