自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

GoLang:你真的了解 HTTPS 嗎?

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
由于筆者對(duì) HTTPS 的認(rèn)知也僅停留在 “HTTPS 比 HTTP 更安全”的層面上,在項(xiàng)目開(kāi)發(fā)中遇到很多通信相關(guān)的問(wèn)題經(jīng)常束手無(wú)策,因此沉下心來(lái),認(rèn)認(rèn)真真學(xué)習(xí)了 HTTPS 并記錄成此文。

一直以來(lái),在實(shí)驗(yàn)室甚至整個(gè)公司特別強(qiáng)調(diào)“安全和隱私”,近半年,筆者在用 GoLang 開(kāi)發(fā)智能邊緣計(jì)算設(shè)備的網(wǎng)絡(luò)通信項(xiàng)目時(shí),常被要求務(wù)必重視“通信的安全和隱私”。期間,對(duì)接了多個(gè)合作方,有的要求“公網(wǎng)下要防止域名劫持”,有的要求“客戶(hù)端上報(bào)要帶‘證書(shū)’啊,更安全”,還有要求除了要用 HTTPS,還要在業(yè)務(wù)邏輯上再進(jìn)行二次哈希、摘要、加密等等。由于筆者對(duì) HTTPS 的認(rèn)知也僅停留在 “HTTPS 比 HTTP 更安全”的層面上,在項(xiàng)目開(kāi)發(fā)中遇到很多通信相關(guān)的問(wèn)題經(jīng)常束手無(wú)策,因此沉下心來(lái),認(rèn)認(rèn)真真學(xué)習(xí)了 HTTPS 并記錄成此文。

一、HTTPS 之靈魂三問(wèn)

要說(shuō) HTTPS,搞 IT 的甚至是不搞 IT 的,都知道:“HTTPS 比 HTTP 安全”。因此但凡要開(kāi)發(fā)涉及網(wǎng)絡(luò)傳輸?shù)捻?xiàng)目時(shí),得到的需求一定有:“要用 HTTPS”。

1. HTTPS 是什么?

維基百科對(duì) HTTPS 的解釋是:

超文本傳輸安全協(xié)議(英語(yǔ):HyperText Transfer Protocol Secure,縮寫(xiě):HTTPS;常稱(chēng)為 HTTP over TLS、HTTP over SSL 或 HTTP Secure)是一種通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)進(jìn)行安全通信的傳輸協(xié)議。HTTPS 經(jīng)由 HTTP 進(jìn)行通信,但利用 SSL/TLS 來(lái)加密數(shù)據(jù)包。HTTPS 開(kāi)發(fā)的主要目的,是提供對(duì)網(wǎng)站服務(wù)器的身份認(rèn)證,保護(hù)交換數(shù)據(jù)的隱私與完整性。這個(gè)協(xié)議由網(wǎng)景公司(Netscape)在 1994 年首次提出,隨后擴(kuò)展到互聯(lián)網(wǎng)上。

抓重點(diǎn):HTTPS=HTTP over SSL/TLS,也就是說(shuō),HTTPS 在傳輸層 TCP 和應(yīng)用層 HTTP 之間,多走了一層 SSL/TLS。

由此可見(jiàn),TLS/SSL 是 HTTPS 的核心! 那么,這個(gè)TLS/SSL又是何方神圣呢?文章How to use SSL/TLS to Secure Your Communications: The Basics指出:

The SSL/TLS protocol functions between two layers of the OSI Presentation layer.The handshake and record layers operate over TCP/IP to encrypt data received directly from the Application layer.

SSL/TLS 協(xié)議作用在傳輸層和應(yīng)用層之間,對(duì)應(yīng)用層數(shù)據(jù)進(jìn)行加密傳輸。

借用文中的圖,可以直觀(guān)感受到:SSL和TLS都是加密協(xié)議。SSL,全稱(chēng) Secure Socket Layer,在 1994 年由網(wǎng)景公司(Netscape)最早提出 1.0 版本;TLS,全稱(chēng) Transport Layer Security,則是 1999 年基于 SSL3.0 版本上改進(jìn)而來(lái)的。官方建議棄用 SSL 而保留和采用 TLS,但是由于歷史原因,SSL 仍然存在,而且很多人已經(jīng)習(xí)慣 SSL 這個(gè)名詞,因此現(xiàn)在索性就叫成 SSL/TLS。

2. HTTPS 為什么?

肯定有不少同學(xué)不假思索:“當(dāng)然是 HTTP 不安全,HTTPS 安全,所以選擇 HTTPS 唄!”那么,HTTPS 比 HTTP“好”在哪里?

維基百科上對(duì) HTTP 的解釋如下:

設(shè)計(jì) HTTP 最初的目的是為了提供一種發(fā)布和接收 HTML 頁(yè)面的方法。

HTTP 的發(fā)展是由蒂姆·伯納斯-李于 1989 年在歐洲核子研究組織(CERN)所發(fā)起。HTTP 的標(biāo)準(zhǔn)制定由萬(wàn)維網(wǎng)協(xié)會(huì)(World Wide Web Consortium,W3C)和互聯(lián)網(wǎng)工程任務(wù)組(Internet Engineering Task Force,IETF)進(jìn)行協(xié)調(diào),最終發(fā)布了一系列的 RFC,其中最著名的是 1999 年 6 月公布的 RFC 2616,定義了 HTTP 協(xié)議中現(xiàn)今廣泛使用的一個(gè)版本——HTTP 1.1。

HTTP 協(xié)議是為了傳輸網(wǎng)頁(yè)超文本(文本、圖像、多媒體資源),以及規(guī)范客戶(hù)端和服務(wù)器端之間互相請(qǐng)求資源的方法的應(yīng)用層協(xié)議。在 1989 年最早推出了 HTTP 0.9 版本,而 1999 年公布的 HTTP 1.1 是到目前(2020 年)仍舊廣泛使用的版本。

但是這個(gè) HTTP 1.1 版本存在一個(gè)很大的問(wèn)題-明文傳輸(Plaintext/Clear Text),這個(gè)問(wèn)題在互聯(lián)網(wǎng)時(shí)代的今天是致命的,一旦數(shù)據(jù)在公共網(wǎng)絡(luò)中被第三方截獲,其通信內(nèi)容輕而易舉地就被竊取了。

因此,HTTPS 應(yīng)運(yùn)而生,它被公認(rèn)的三大優(yōu)勢(shì)有:

  • 數(shù)據(jù)加密,防竊聽(tīng)
  • 身份驗(yàn)證,防冒充
  • 完整性校驗(yàn),防篡改

啰嗦說(shuō)一句:第 1 點(diǎn)確實(shí)是解決了 HTTP 明文傳輸;至于第 2 和第 3 點(diǎn),其他一些應(yīng)用層協(xié)議也會(huì)遇到(服務(wù)端被冒充、數(shù)據(jù)被篡改是網(wǎng)絡(luò)傳輸中“較常見(jiàn)”的問(wèn)題)。

再插一句題外話(huà):2015 年推出的 HTTP 2 在 HTTP 1.1 的基礎(chǔ)上有很大改進(jìn),其中一點(diǎn)就是 HTTPS。

3. HTTPS 怎么做?

本文接下來(lái)將從 HTTPS 的 3 個(gè)優(yōu)勢(shì)展開(kāi)說(shuō)明,即:

  • 數(shù)據(jù)加密,即 HTTPS 是怎么進(jìn)行數(shù)據(jù)加密的。本章介紹 HTTPS 中的對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密
  • 身份驗(yàn)證,即 HTTPS 是怎么讓客戶(hù)端相信“發(fā)給我數(shù)據(jù)的服務(wù)端是我想要的服務(wù)器”。本章介紹 HTTPS 的 CA 和證書(shū)
  • 完整性校驗(yàn),即 HTTPS 是怎么做數(shù)據(jù)完整性校驗(yàn)以防止被篡改。本章介紹 HTTPS 的哈希

最后,為了整篇文章的完整性,還會(huì)增加以下幾個(gè)內(nèi)容:

  • HTTPS 流程,即客戶(hù)端和服務(wù)器端 HTTPS 通信全過(guò)程
  • 實(shí)際問(wèn)題,記錄了筆者在實(shí)戰(zhàn)中遇到 HTTPS 相關(guān)問(wèn)題

二、數(shù)據(jù)加密:HTTPS 的對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密

相信不少同學(xué)會(huì)說(shuō)"對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密有什么好講的?前者只有一把密鑰做加解密;后者有兩把密鑰,公鑰和私鑰,互為加解密,公鑰給對(duì)方,私鑰自己用。HTTPS 兩者都有。好了,這章可以結(jié)束啦。"

三個(gè)問(wèn)題:

  • HTTPS 為什么同時(shí)要有對(duì)稱(chēng)加密和非堆成加密兩種加密方式?
  • HTTPS 對(duì)稱(chēng)加密的密鑰(本文稱(chēng)為 SK,下同)如何產(chǎn)生和傳輸?
  • HTTPS 的有幾套非對(duì)稱(chēng)加密?目的是什么?是否可以省略?

好,一個(gè)問(wèn)題一個(gè)問(wèn)題來(lái)。

問(wèn)題 1:HTTPS 為什么同時(shí)要有對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密兩種加密方式?

默認(rèn)各位同學(xué)已經(jīng)知曉對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密(了解基本原理即可),不清楚的同學(xué)推薦閱讀知乎文章-《對(duì)稱(chēng)加密與非對(duì)稱(chēng)加密》,文章最后指出了這兩個(gè)加密方式的優(yōu)缺點(diǎn),原文如下:

(1)對(duì)稱(chēng)加密加密與解密使用的是同樣的密鑰,所以速度快,但由于需要將密鑰在網(wǎng)絡(luò)傳輸,所以安全性不高。

(2) 非對(duì)稱(chēng)加密使用了一對(duì)密鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。

那么解決辦法有嗎?有,文章隨后說(shuō)道:

(3)解決的辦法是將對(duì)稱(chēng)加密的密鑰使用非對(duì)稱(chēng)加密的公鑰進(jìn)行加密,然后發(fā)送出去,接收方使用私鑰進(jìn)行解密得到對(duì)稱(chēng)加密的密鑰,然后雙方可以使用對(duì)稱(chēng)加密來(lái)進(jìn)行溝通。

確實(shí),HTTPS(最開(kāi)始)就是這么做的!其思路大致如下:

  • 首先一定要明確HTTPS既有對(duì)稱(chēng)加密,又有非對(duì)稱(chēng)加密。
  • 由于對(duì)稱(chēng)加密性能高速度快,因此在傳輸數(shù)據(jù)時(shí)(也就是對(duì)話(huà)內(nèi)容)采用對(duì)稱(chēng)加密。
  • 但是對(duì)稱(chēng)加密的密鑰SK,既沒(méi)辦法預(yù)先設(shè)置(密鑰不可能只有一把,服務(wù)器端維護(hù)大量密鑰也不具備可行性),因此只能選擇在對(duì)話(huà)前通過(guò)網(wǎng)絡(luò)協(xié)商出一把新的SK。
  • 為了確保SK的傳輸安全,使用非對(duì)稱(chēng)加密來(lái)協(xié)商SK。

HTTPS 的這種設(shè)計(jì)同時(shí)兼顧了安全和效率,贊嘆先驅(qū)們的智慧!

問(wèn)題 2:HTTPS 對(duì)稱(chēng)加密的密鑰 SK 如何產(chǎn)生和傳輸?

通過(guò)第一個(gè)問(wèn)題,我們知道了 HTTPS 分為2 個(gè)過(guò)程:

  • 協(xié)商對(duì)稱(chēng)加密密鑰 SK 的非對(duì)稱(chēng)加密階段,稱(chēng)為T(mén)LS 握手階段。
  • 使用 SK 對(duì)數(shù)據(jù)(對(duì)話(huà)內(nèi)容)進(jìn)行對(duì)稱(chēng)加密的階段,稱(chēng)為數(shù)據(jù)通信階段。

過(guò)程 2數(shù)據(jù)通信階段:發(fā)送端首先用密鑰 SK 對(duì)通信內(nèi)容進(jìn)行對(duì)稱(chēng)加密,接著通過(guò)網(wǎng)絡(luò)傳輸出去;對(duì)端收到數(shù)據(jù)后,用 SK 先將數(shù)據(jù)解密,于是就得到了通信內(nèi)容。這里筆者有一個(gè)問(wèn)題尚未求證:在數(shù)據(jù)傳輸過(guò)程中,是否會(huì)對(duì)通信數(shù)據(jù)進(jìn)行哈希以確保其不被篡改?姑且記一筆。

過(guò)程 1TLS 握手階段:協(xié)商密鑰 SK。網(wǎng)上關(guān)于這個(gè)知識(shí)點(diǎn)的文章有很多,然而一些已經(jīng)過(guò)時(shí),一些則不全。就協(xié)商密鑰 SK 這塊,筆者推薦《掃盲 HTTPS 和 SSL/TLS 協(xié)議[3]:密鑰交換(密鑰協(xié)商)算法及其原理》和《密鑰協(xié)商機(jī)制》。本文直接扔出結(jié)論,HTTPS 協(xié)商對(duì)稱(chēng)加密密鑰 SK 的辦法有很多種,介紹 3 種較為常見(jiàn)的辦法:

  • 基于非對(duì)稱(chēng)加密算法
  • 基于專(zhuān)用密鑰交換算法,常見(jiàn)有 DH、ECDH 等
  • 基于共享的 secret,常見(jiàn)有 PSK,SRP 等

(1) 方法 1:基于非對(duì)稱(chēng)加密算法

維基百科對(duì)于非對(duì)稱(chēng)加密算法的解釋?zhuān)汗_(kāi)密鑰密碼學(xué)(英語(yǔ):Public-key cryptography)也稱(chēng)非對(duì)稱(chēng)式密碼學(xué)(英語(yǔ):Asymmetric cryptography)是密碼學(xué)的一種算法,它需要兩個(gè)密鑰,一個(gè)是公開(kāi)密鑰,另一個(gè)是私有密鑰;一個(gè)用作加密,另一個(gè)則用作解密。使用其中一個(gè)密鑰把明文加密后所得的密文,只能用相對(duì)應(yīng)的另一個(gè)密鑰才能解密得到原本的明文;甚至連最初用來(lái)加密的密鑰也不能用作解密。由于加密和解密需要兩個(gè)不同的密鑰,故被稱(chēng)為非對(duì)稱(chēng)加密;不同于加密和解密都使用同一個(gè)密鑰的對(duì)稱(chēng)加密。雖然兩個(gè)密鑰在數(shù)學(xué)上相關(guān),但如果知道了其中一個(gè),并不能憑此計(jì)算出另外一個(gè);因此其中一個(gè)可以公開(kāi),稱(chēng)為公鑰,任意向外發(fā)布;不公開(kāi)的密鑰為私鑰,必須由用戶(hù)自行嚴(yán)格秘密保管,絕不透過(guò)任何途徑向任何人提供,也不會(huì)透露給被信任的要通信的另一方。

非對(duì)稱(chēng)加密 RSA 協(xié)商密鑰的辦法,是 HTTPS(嚴(yán)格說(shuō)是 SSL/TLS 協(xié)議)最早的辦法,其過(guò)程如下:

  • 客戶(hù)端給服務(wù)端發(fā)送請(qǐng)求;
  • 服務(wù)端返回客戶(hù)端自己的公鑰 PuK;
  • 客戶(hù)端產(chǎn)生本次對(duì)話(huà)的對(duì)稱(chēng)密鑰 SK,并用 PuK 進(jìn)行加密得到 SK_Enc 后傳給服務(wù)端;
  • 服務(wù)端收到 SK_Enc 后用自己的私鑰 PrK 解密得到 SK;若成功,則返回客戶(hù)端 OK,否則終止對(duì)話(huà).
  • 接下來(lái),客戶(hù)端和服務(wù)端的對(duì)話(huà)均用 SK 加密后傳輸。

(2) 方法 2:基于專(zhuān)用密鑰交換算法

方法 1 是被大部分人熟知的,但是存在一個(gè)問(wèn)題:如果服務(wù)端的私鑰 PrK 泄露了,那么 HTTPS 所做的加密也就不安全了。

因此,就有了密鑰交換算法(有說(shuō)法是 keyless 方法)。方法原理筆者沒(méi)有深究(數(shù)學(xué)功底有限,看到大量的公式證明還是會(huì)煩…),DH 和 ECDH 協(xié)商密鑰算法大致過(guò)程如下:

ECDH 算法中的 A 和 B,在有的材料中也被稱(chēng)為PreMaster-Secret。最終協(xié)商得到的密鑰 SK 也被稱(chēng)為Master Secret,也被稱(chēng)為Session Key。

直接給出結(jié)論:ECDH 比 DH 算法更快,有說(shuō)法是 10 倍;而且 ECDH 比 DH 更難破解,可行性更好。

(3) 方法 3:基于共享的 secret

這類(lèi)做法就是在客戶(hù)端和服務(wù)端預(yù)設(shè)好對(duì)稱(chēng)加密密鑰,握手階段只需要傳遞類(lèi)似鑰匙 id 即可。代表算法有 PSK。

問(wèn)題 3:HTTPS 的有幾套非對(duì)稱(chēng)加密?目的是什么?是否可以省略?

直接給出答案:2 套非對(duì)稱(chēng)加密。

第一套用于協(xié)商對(duì)稱(chēng)加密密鑰 SK(問(wèn)題 2 一直在討論的內(nèi)容);第二套用于數(shù)字證書(shū)簽名加密(接下來(lái)一章會(huì)詳細(xì)討論 CA 證書(shū))。這兩者的區(qū)別是:前者是服務(wù)器端(如果是雙向驗(yàn)證的話(huà),客戶(hù)端也會(huì)有一套非對(duì)稱(chēng)加密公私鑰)產(chǎn)生的。私鑰在服務(wù)端上;后者是 CA 機(jī)構(gòu)產(chǎn)生的,私鑰在 CA 機(jī)構(gòu)那邊。

并且,這 2 套都不可以省略。(這個(gè)說(shuō)法略不嚴(yán)謹(jǐn),但是在實(shí)際操作中,確實(shí)都不建議省略。)

三、身份驗(yàn)證:HTTPS 的證書(shū)

筆者認(rèn)為,對(duì)大部分程序員來(lái)說(shuō),工作中遇到的 HTTPS 相關(guān)問(wèn)題,80%~90%都是跟證書(shū)相關(guān)的。因此,了解證書(shū)非常關(guān)鍵!

1. 證書(shū)是什么?

解釋這個(gè)問(wèn)題之前,先看幾個(gè)關(guān)鍵詞:CA,CA 機(jī)構(gòu),數(shù)字證書(shū),數(shù)字簽名,(證書(shū))指紋,(CA)證書(shū),HTTPS 證書(shū),SSL/TLS 證書(shū)。

理一理上面這些關(guān)鍵詞之間的關(guān)系:

  • CA,CA 機(jī)構(gòu):機(jī)構(gòu)/組織概念。
  • 數(shù)字證書(shū),(CA)證書(shū),HTTPS 證書(shū),SSL/TLS 證書(shū):CA 簽發(fā)的數(shù)字證書(shū)。
  • 數(shù)字簽名,(證書(shū))指紋:CA 簽發(fā)的證書(shū)的內(nèi)容之一,一段加密的密文。

智庫(kù)百科對(duì)數(shù)字證書(shū)的解釋是:

數(shù)字證書(shū)也稱(chēng)公開(kāi)密鑰證書(shū),是指用于電子信息活動(dòng)中電子文件行為主體的驗(yàn)證和證明,并可實(shí)現(xiàn)電子文件保密性和完整性的電子數(shù)據(jù)。數(shù)字證書(shū)是一個(gè)經(jīng)證書(shū)認(rèn)證中心(Certification Authority,簡(jiǎn)稱(chēng) CA)發(fā)行的文件。

數(shù)字證書(shū)包含有行為主體信息和證書(shū)認(rèn)證機(jī)構(gòu)的數(shù)字簽名。數(shù)字簽名是指以電子形式存在,可依附在電子文件中用于辨識(shí)電子文件的簽署者及表示對(duì)該電子文件內(nèi)容負(fù)責(zé)所使用的電子數(shù)字標(biāo)識(shí)。

抓重點(diǎn):數(shù)字證書(shū)用于主體身份驗(yàn)證。

首先,數(shù)字證書(shū)=主體信息+數(shù)字簽名。

Windows 下,我們可以在 Chrome 瀏覽器上點(diǎn)擊地址欄的“鎖”標(biāo)記后會(huì)出現(xiàn)下拉框,接著點(diǎn)擊“證書(shū)”即可看到通過(guò) HTTPS 訪(fǎng)問(wèn)該服務(wù)器時(shí)的數(shù)字證書(shū)。具體操作如下:

  • 證書(shū)“常規(guī)”頁(yè)面,是關(guān)于該證書(shū)的一個(gè)籠統(tǒng)介紹,包括簽發(fā)該證書(shū)的 CA 機(jī)構(gòu)、該證書(shū)綁定的域名(頒發(fā)給)、證書(shū)有效期。
  • 證書(shū)“詳細(xì)信息”頁(yè)面,以鍵值對(duì)形式展示了這張證書(shū)的完整內(nèi)容。(后文將詳細(xì)介紹證書(shū)內(nèi)容)
  • 證書(shū)的“證書(shū)路徑”,以層級(jí)結(jié)構(gòu)展示了從該證書(shū)綁定的域名一直到根證書(shū)的路徑,這就是證書(shū)鏈。(后文會(huì)展開(kāi)介紹證書(shū)鏈)

看完了 Chrome 瀏覽器上的證書(shū),在讓我們通過(guò) Wireshark 抓包來(lái)來(lái)看看數(shù)字證書(shū):

對(duì)比 Chrome 上看到的數(shù)字證書(shū)和 Wireshark 抓包得到的數(shù)字證書(shū),可以看到兩者呈現(xiàn)的證書(shū)內(nèi)容是一致的??偨Y(jié)來(lái)看,一張完整的數(shù)字證書(shū)包括:

  • 主體的必要信息:版本(version)、序列號(hào)(serialNumber)、簽名算法(signatureAlgorithm)、頒發(fā)者(issuer)、有效期(validity)、使用者(subject)、公鑰信息(subjectPublicKeyInfo)
  • 主體的擴(kuò)展信息(extension):如密鑰標(biāo)識(shí)符、證書(shū)策略等
  • 數(shù)字簽名(signature),也稱(chēng)指紋

抽象為下圖:

2.  為什么是數(shù)字證書(shū)呢?

HTTPS 已經(jīng)對(duì)通信數(shù)據(jù)進(jìn)行了加密,為什么還要驗(yàn)證身份?說(shuō)好的“人與人之間最基本的信任呢?”

這還不是因?yàn)楦髀泛诳?、駭客們總是在制造各種攻擊嗎?(捂臉)其中一個(gè)大名鼎鼎的中間人攻擊(Man-In-The-Middle Attack,MITM 攻擊),簡(jiǎn)單的講,“中間人”在客戶(hù)端和服務(wù)端都不知情的情況下,夾在雙方之間竊聽(tīng)甚至篡改通信信息,過(guò)程見(jiàn)下圖(圖引自《HTTPS 中間人攻擊實(shí)踐(原理·實(shí)踐)》):

在 HTTPS 的握手階段,一端向?qū)Χ税l(fā)送請(qǐng)求,對(duì)端返回自己的公鑰;而一端未驗(yàn)證對(duì)方的身份和公鑰,直接協(xié)商密鑰。“中間人”看到了這個(gè)漏洞,夾在中間截獲了對(duì)端的公鑰,替換成了自己的公鑰。正是這步“拿錯(cuò)了公鑰”或者說(shuō)“信錯(cuò)了對(duì)端”,使得 HTTPS 為加密(密鑰協(xié)商的非對(duì)稱(chēng)加密和通信數(shù)據(jù)的對(duì)稱(chēng)加密)所做的努力全部泡湯。

可見(jiàn),在 HTTPS 中,“確保對(duì)端身份正確”即“確保拿到的公鑰正確”,而在網(wǎng)絡(luò)通信中所謂的“身份”,一般指的是通信一端的域名、IP 地址甚至是Mac 地址。所以,數(shù)字證書(shū)同時(shí)包含了通信一端的身份信息和公鑰信息。

但是數(shù)字證書(shū)會(huì)在網(wǎng)絡(luò)中傳輸(由被要求驗(yàn)證身份的一端通過(guò)網(wǎng)絡(luò)傳給另一端),這就意味著證書(shū)也可能會(huì)被竊取篡改。這個(gè)時(shí)候權(quán)威的 CA 機(jī)構(gòu)就出馬了,他想了個(gè)辦法:加了一個(gè)“防偽標(biāo)識(shí)”— 數(shù)字簽名。具體做法如下:

  1. signature = RSA(PriKey_CA, Hash(message)) 

這里啰嗦幾句:數(shù)字簽名生成過(guò)程是首先對(duì)原文作哈希,把一段不定長(zhǎng)的文本映射成固定長(zhǎng)度的字符空間,接著再用 CA 機(jī)構(gòu)的私鑰對(duì)這段定長(zhǎng)字符做加密。大大提高了整體的運(yùn)算效率。

3. 證書(shū)是怎么工作的?

要了解證書(shū)是怎么做“身份驗(yàn)證”,即“防冒充”,得從 2 個(gè)角度來(lái)說(shuō)明:

  • 申請(qǐng)證書(shū),即需要被驗(yàn)證身份的一端,需要申請(qǐng)一份能夠驗(yàn)證自己身份的證書(shū)
  • 驗(yàn)證證書(shū),即需要驗(yàn)證對(duì)方身份的一端,拿到證書(shū)后驗(yàn)證對(duì)端的身份

請(qǐng)注意,這里有一個(gè)前提:這張證書(shū)必須是由權(quán)威 CA 機(jī)構(gòu)頒發(fā)的,且尚在有效期內(nèi);或者是一張信任的私人證書(shū)。

(1) 申請(qǐng)證書(shū)

CA 機(jī)構(gòu)和證書(shū)的分類(lèi)本文不討論,這里我們討論正規(guī)權(quán)威 CA 機(jī)構(gòu)簽發(fā)的證書(shū),至于是 DV、OV 還是 EV,只是安全強(qiáng)度問(wèn)題,工作原理是一樣的。

總結(jié)申請(qǐng)證書(shū)的過(guò)程:用戶(hù)向 CA 機(jī)構(gòu)提交自己的信息(如域名)和公鑰(用戶(hù)自己生成的非對(duì)稱(chēng)加密公鑰,用于 TLS 握手階段和另一端協(xié)商密鑰用),CA 機(jī)構(gòu)生成數(shù)字證書(shū),如下圖:

(2) 驗(yàn)證證書(shū)

收到對(duì)端發(fā)過(guò)來(lái)的證書(shū),執(zhí)行證書(shū)申請(qǐng)的“逆過(guò)程”即可,總結(jié)如下圖:

接受證書(shū)的一端先對(duì)除數(shù)簽名的其他部分做一次相同的哈希算法(證書(shū)中指明了哈希算法),得到這段文本的哈希映射,記作 H1;獲取 CA 機(jī)構(gòu)的公鑰對(duì)數(shù)字簽名屬性做解碼,得到了 CA 機(jī)構(gòu)計(jì)算出的哈希映射,記作 H2。對(duì)比 H1 和 H2 兩個(gè)字符串是否嚴(yán)格相等,若是,代表該證書(shū)的信息未被篡改,證書(shū)有效;否則,證書(shū)內(nèi)容被篡改,證書(shū)無(wú)效。

若證書(shū)有效,接受端會(huì)再進(jìn)行對(duì)端的身份校驗(yàn)(驗(yàn)證域名),若身份驗(yàn)證通過(guò),接收端會(huì)拿證書(shū)上的公鑰(也是對(duì)端自己生產(chǎn)的非對(duì)稱(chēng)加密公鑰)加密接下來(lái)整個(gè) TLS 握手階段的信息之后,發(fā)送給對(duì)端。

這個(gè)過(guò)程中有一個(gè)問(wèn)題:CA 機(jī)構(gòu)的公鑰怎么獲取?

回答:提前內(nèi)置。

眾所周知,操作系統(tǒng)和瀏覽器在軟件安裝階段會(huì)在其特定目錄下放置一堆的證書(shū)。如 Windows 的根證書(shū)管理在 certmgr 下:

這些證書(shū)都有個(gè)特點(diǎn):權(quán)威 CA 機(jī)構(gòu)發(fā)布的根證書(shū)(Root Certificate)。根證書(shū)有幾個(gè)特點(diǎn):

  • 沒(méi)有上層機(jī)構(gòu)再為其本身作數(shù)字簽名
  • 證書(shū)上的公鑰即為 CA 機(jī)構(gòu)發(fā)布的公鑰
  • 權(quán)威 CA 機(jī)構(gòu)的自簽證書(shū)

而這些根證書(shū)會(huì)跟很多軟件,包括操作系統(tǒng)、瀏覽器一起被安裝到用戶(hù)設(shè)備上。即使沒(méi)有被提前安裝好,這些根證書(shū)也可以在 CA 機(jī)構(gòu)的官網(wǎng)上獲取得到。

目前全球大型權(quán)威 CA 機(jī)構(gòu)有 Symantec、GeoTrust、Comodo 以及 RapidSSL 等,并且這些機(jī)構(gòu)頒發(fā)的 SSL 數(shù)字證書(shū),在市場(chǎng)的占有率是非常的高。(節(jié)選自《SSL 證書(shū)頒發(fā)機(jī)構(gòu)有哪些》)

本地被內(nèi)置了這么多的根證書(shū),那要怎么知道我這份證書(shū)應(yīng)該要用哪一個(gè)根證書(shū)來(lái)驗(yàn)證呢?

回答:證書(shū)信任鏈。

在信任鏈上有 3 類(lèi)證書(shū):根證書(shū),中介證書(shū)和用戶(hù)證書(shū)。根證書(shū)前文已有說(shuō)明,用戶(hù)證書(shū)就是對(duì)端發(fā)過(guò)來(lái)的證書(shū),或者說(shuō)是用戶(hù)向權(quán)威 CA 機(jī)構(gòu)綁定了自己身份(主要指域名)和自己公鑰的證書(shū)。中介證書(shū)可以理解由權(quán)威 CA 機(jī)構(gòu)委派的代理機(jī)構(gòu)簽發(fā)的數(shù)字證書(shū),推薦閱讀《What is an intermediate certificate?》。中介證書(shū)或者說(shuō)是中介機(jī)構(gòu)的存在是為了保證根證書(shū)的密鑰的安全性。

細(xì)心的同學(xué)仔細(xì)看一看 certmgr 會(huì)發(fā)現(xiàn)有一個(gè)分類(lèi)是“中間證書(shū)頒發(fā)機(jī)構(gòu)”,這里存放的就是中介證書(shū)。用戶(hù)證書(shū)絕大多數(shù)是通過(guò)權(quán)威的 CA 機(jī)構(gòu)的代理中介機(jī)構(gòu)頒發(fā)。

這么來(lái)說(shuō),根據(jù)對(duì)端發(fā)來(lái)的用戶(hù)證書(shū)尋找對(duì)應(yīng)的根證書(shū)豈不是更困難了?

自問(wèn)自答:這是一個(gè)在樹(shù)形數(shù)據(jù)結(jié)構(gòu)中,從葉子節(jié)點(diǎn)搜索根節(jié)點(diǎn)的過(guò)程,直接一個(gè)最原始的深搜(DFS)不就可以了嘛?舉例說(shuō)明,如下圖(引自Wikipedia-Chain of trust):

  • 從用戶(hù)證書(shū)開(kāi)始。
  • 記“Issuer”字段的值為 i1,搜索本地證書(shū),尋找由“Subject”為 i1 的證書(shū)。
  • 若沒(méi)有找到,結(jié)束返回證書(shū)無(wú)效;否則,跳到步驟 4)。
  • 判斷該證書(shū)的 Issuer 值是否等于 Subject 值。
  • 若是,則該證書(shū)是根證書(shū),結(jié)束返回該證書(shū);否則跳到步驟 6)。
  • 以該證書(shū)開(kāi)始,跳轉(zhuǎn) 2)(繼續(xù)搜索)。

更多關(guān)于信任鏈的知識(shí)點(diǎn),推薦閱讀《What is the SSL Certificate Chain?》

4. 證書(shū)怎么樣?

相信不少同學(xué)或多或少接觸過(guò)證書(shū)文件,比如.pem、.crt、.cer、.key 等,于是問(wèn)題就來(lái)了:

“為什么有這么多不同后綴名的證書(shū)啊?他們有什么聯(lián)系和區(qū)別?”

回答這個(gè)問(wèn)題要從 3 個(gè)層面來(lái)分析:

  • 證書(shū)標(biāo)準(zhǔn)
  • 證書(shū)編碼格式
  • 文件擴(kuò)展名

(1) 證書(shū)標(biāo)準(zhǔn)

數(shù)字證書(shū)的格式普遍采用的是 X.509 國(guó)際標(biāo)準(zhǔn),維基百科對(duì)于 X.509 解釋如下:

X.509 是密碼學(xué)里公鑰證書(shū)的格式標(biāo)準(zhǔn)。X.509 證書(shū)已應(yīng)用在包括 TLS/SSL 在內(nèi)的眾多網(wǎng)絡(luò)協(xié)議里,同時(shí)它也用在很多非在線(xiàn)應(yīng)用場(chǎng)景里,比如電子簽名服務(wù)。X.509 證書(shū)里含有公鑰、身份信息(比如網(wǎng)絡(luò)主機(jī)名,組織的名稱(chēng)或個(gè)體名稱(chēng)等)和簽名信息(可以是證書(shū)簽發(fā)機(jī)構(gòu) CA 的簽名,也可以是自簽名)。對(duì)于一份經(jīng)由可信的證書(shū)簽發(fā)機(jī)構(gòu)簽名或者可以通過(guò)其它方式驗(yàn)證的證書(shū),證書(shū)的擁有者就可以用證書(shū)及相應(yīng)的私鑰來(lái)創(chuàng)建安全的通信,對(duì)文檔進(jìn)行數(shù)字簽名。

X.509 是 ITU-T 標(biāo)準(zhǔn)化部門(mén)基于他們之前的 ASN.1 定義的一套證書(shū)標(biāo)準(zhǔn)。

(2) 證書(shū)的編碼格式

X.509 標(biāo)準(zhǔn)的證書(shū)文件具有不同的編碼格式:PEM 和 DER。

  • PEM:

PEM,全稱(chēng) Privacy Enhanced Mail,以文本格式存儲(chǔ),以 -----BEGIN

XXX-----開(kāi)頭、-----END XXX-----結(jié)尾,中間內(nèi)容是 BASE64 編碼數(shù)據(jù)。其文本內(nèi)容大概如下:

  1. html -----BEGIN CERTIFICATE----- Base64編碼過(guò)的證書(shū)數(shù)據(jù) -----END CERTIFICATE----- 

通常,PEM 格式可以存儲(chǔ)公鑰、私鑰、證書(shū)簽名請(qǐng)求等數(shù)據(jù)。查看 PEM 格式證書(shū)的信息一般采用如下命令:

  1. openssl x509 -in xxx.pem -text -noout 

Apache 和 Nginx 服務(wù)器偏向于使用這種編碼格式。

  • DER:

DER,全稱(chēng) Distinguished Encoding Rules,以二進(jìn)制存儲(chǔ),因此文件結(jié)構(gòu)無(wú)法直接預(yù)覽,只能通過(guò)如下命令查看:

  1. html openssl x509 -in xxx.der -inform der -text -noout 

DER 格式也可以存儲(chǔ)公鑰、私鑰、證書(shū)簽名請(qǐng)求等數(shù)據(jù)。Java 和 Windows 應(yīng)用偏向于使用這種編碼格式。

當(dāng)然同一 X.509 證書(shū)的不同編碼之間可以互相轉(zhuǎn)換:

  • PEM 轉(zhuǎn)為 DER:
    1. openssl x509 -in xxx.pem -outform der -out xxx.der 
  • DER 轉(zhuǎn)為 PEM:
    1. openssl x509 -in xxx.der -inform der -outform pem -out xxx.pem 

(3) 文件擴(kuò)展名

不同的擴(kuò)展名可以分為以下幾類(lèi):

  • 證書(shū):存放數(shù)字證書(shū),X.509 標(biāo)準(zhǔn),格式可能是 PEM 或 DER。.crt、.cer
  • 密鑰:用來(lái)存放一個(gè) RSA 公鑰或私鑰,這類(lèi)文件不是 X.509 標(biāo)準(zhǔn),但是是 PEM 或 DER 格式。后綴名有.key。
  • 證書(shū)+密鑰:可同時(shí)存放證書(shū)和 RSA 公鑰/.pem、.der、.p12
  • 證書(shū)請(qǐng)求:并不是證書(shū),而是證書(shū)簽名請(qǐng)求。csr

四、完整性校驗(yàn):HTTPS 的哈希

哈希,鍵值對(duì)數(shù)據(jù)結(jié)構(gòu),通過(guò)哈希函數(shù)把一個(gè)空間映射到另一個(gè)空間。非常好用的一個(gè)工具,而且哪哪兒都有它的影子,比如負(fù)載均衡的一致性哈希、密碼學(xué)中用于信息加密或數(shù)據(jù)校驗(yàn)的各種哈希(SHA、MD5 等)、二維空間定位的 GeoHash、對(duì)象相似度的 SimHash 等等。

HTTPS 的的哈希一共用在 2 個(gè)地方:

1. 證書(shū)的數(shù)字簽名

具體做法在上文證書(shū)一章節(jié)已經(jīng)說(shuō)過(guò),不再贅述。在這里使用哈希的目的主要是為了減少非對(duì)稱(chēng)加密算法 RSA 在長(zhǎng)文本上的開(kāi)銷(xiāo)。

2. 對(duì)稱(chēng)加密的 Message Digest

在數(shù)據(jù)通信階段,SSL/TLS 會(huì)對(duì)原始消息(message)做一次哈希,得到該消息 message 的摘要,稱(chēng)為消息摘要(Message Digest)。對(duì)端接受到消息后,使用協(xié)商出來(lái)的對(duì)稱(chēng)加密密鑰解密數(shù)據(jù)包,得到原始消息 message;接著也做一次相同的哈希算法得到摘要,對(duì)比發(fā)送過(guò)來(lái)的消息摘要和計(jì)算出的消息摘要是否一致,可以判斷通信數(shù)據(jù)是否被篡改。

五、HTTPS 通信流程

到此,HTTPS 涉及到的關(guān)鍵問(wèn)題基本都覆蓋了。本章總結(jié)整個(gè) HTTPS 的通信過(guò)程:

補(bǔ)充說(shuō)明幾點(diǎn):

1. 協(xié)商密鑰:客戶(hù)端/服務(wù)端隨機(jī)數(shù)、Client/Server Key

在加密一章節(jié)介紹的 ECDH 是停留在原理層面,實(shí)際中密鑰協(xié)商除了 PreMaster-Secret(即 Client/Server Key)之外,還有客戶(hù)端和服務(wù)端隨機(jī)數(shù)參與,參考文章《Https:TLS 握手協(xié)議》,引用文中的圖來(lái)自展示實(shí)際 ECDH 秘鑰協(xié)商的做法:

 

2. Change Cipher Spec

Change Cipher Spec是通知對(duì)方需要加密參數(shù)。文章《TLSde 改變密碼標(biāo)準(zhǔn)協(xié)議(Change Cipher Spec Protocol)》指出:

SSL 修改密文協(xié)議的設(shè)計(jì)目的是為了保障 SSL 傳輸過(guò)程的安全性,因?yàn)?SSL 協(xié)議要求客戶(hù)端或服務(wù)器端每隔一段時(shí)間必須改變其加解密參數(shù)。當(dāng)某一方要改變其加解密參數(shù)時(shí),就發(fā)送一個(gè)簡(jiǎn)單的消息通知對(duì)方下一個(gè)要傳送的數(shù)據(jù)將采用新的加解密參數(shù),也就是要求對(duì)方改變?cè)瓉?lái)的安全參數(shù)。

SSL 修改密文協(xié)議是使用 SSL 記錄協(xié)議服務(wù)的 SSL 高層協(xié)議的 3 個(gè)特定協(xié)議之一,也是其中最簡(jiǎn)單的一個(gè)。協(xié)議由單個(gè)消息組成,該消息只包含一個(gè)值為 1 的單個(gè)字節(jié)。該消息的唯一作用就是使未決狀態(tài)復(fù)制為當(dāng)前狀態(tài),更新用于當(dāng)前連接的密碼組。為了保障 SSL 傳輸過(guò)程的安全性,雙方應(yīng)該每隔一段時(shí)間改變加密規(guī)范。

3. Encrypted Handshake Message

Encrypted Handshake Message作用就是確認(rèn)協(xié)商出來(lái)的對(duì)稱(chēng)加密密鑰 SK 的正確性,在客戶(hù)端和服務(wù)端協(xié)商得到對(duì)稱(chēng)加密密鑰 SK 之后,互相給對(duì)方發(fā)了一條用 SK 加密的消息,如果這個(gè)加密的消息被解密校驗(yàn)成功,那么就說(shuō)明對(duì)稱(chēng)加密密鑰 SK 是正確的。

4. 單向驗(yàn)證和雙向驗(yàn)證

本章全部所探討的案例都是基于單向驗(yàn)證,即客戶(hù)端向服務(wù)端請(qǐng)求證書(shū)、驗(yàn)證服務(wù)端身份。在一些實(shí)際場(chǎng)景中,對(duì)安全性的要求更高,有服務(wù)端要求驗(yàn)證客戶(hù)端的身份,即雙向驗(yàn)證。雙向驗(yàn)證在單向驗(yàn)證基礎(chǔ)上,增加“在服務(wù)端發(fā)送證書(shū)之后,向客戶(hù)端發(fā)送‘請(qǐng)求證書(shū)’請(qǐng)求,接著驗(yàn)證客戶(hù)端身份”這個(gè)步驟。參考下圖(圖片出處不查):

六、HTTPS 實(shí)戰(zhàn)問(wèn)題記錄

1. 問(wèn)題:HTTPS 是否需要做域名劫持?

沒(méi)必要。

原因如下:https 在證書(shū)校驗(yàn)這步,客戶(hù)端除了通過(guò)對(duì)比數(shù)字簽名來(lái)校驗(yàn)證書(shū)的有效性,還會(huì)比較證書(shū)上的域名是否與自己要訪(fǎng)問(wèn)的域名一致。因此,只要服務(wù)器的證書(shū)是可信的且客戶(hù)端不跳過(guò)“證書(shū)驗(yàn)證”這個(gè)步驟,https 能夠防止域名劫持。

筆者在實(shí)際中做過(guò)防止域名劫持的工作,具體做法是:首先,客戶(hù)端向可信賴(lài)的域名服務(wù)器請(qǐng)求域名對(duì)應(yīng)的 IP 地址;接著,客戶(hù)端用 IP 替換域名進(jìn)行網(wǎng)絡(luò)請(qǐng)求。被稱(chēng)為HTTPS 的 IP 直連。但在實(shí)際中會(huì)遇到了一個(gè)問(wèn)題:域名身份不對(duì)。根本解決方案是:1).書(shū)校驗(yàn)時(shí),選擇自己定義的 hostname 進(jìn)行校驗(yàn);2).證書(shū)校驗(yàn)前,把 URL 的 IP 替換回域名。在很多語(yǔ)言實(shí)現(xiàn)中,解決方案更為簡(jiǎn)單:在請(qǐng)求頭部的增加 host-name 字段,值填入域名即可。

2. 問(wèn)題:"x509: certificate signed by unknown authority"

這個(gè)問(wèn)題是客戶(hù)端拿到了服務(wù)器的證書(shū)要進(jìn)行身份驗(yàn)證,但是通過(guò)證書(shū)信任鏈策略發(fā)現(xiàn)中間斷了,搜索不到根證書(shū)。說(shuō)白了就是客戶(hù)端本地沒(méi)有簽發(fā)這個(gè)用戶(hù)證書(shū)的根證書(shū)或中介證書(shū)。

實(shí)際中的解決辦法有:1). 缺啥裝啥,沒(méi)有根證書(shū)/中介證書(shū),那就安裝上;2).跳過(guò)證書(shū)身份驗(yàn)證這步。GoLang 中跳過(guò)身份驗(yàn)證的實(shí)現(xiàn):

  1. client := &http.Client{ 
  2.     Transport: &http.Transport{ 
  3.         TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 
  4.     } 

3. 問(wèn)題:https 項(xiàng)目中,服務(wù)端怎么管理證書(shū)和 RSA 密鑰?

看情況。

如果是正規(guī)的公司,一般會(huì)有統(tǒng)一的接入層幫忙做掉,后臺(tái)開(kāi)發(fā)程序員只需要關(guān)心自己的業(yè)務(wù)邏輯即可。運(yùn)維同事或者是負(fù)責(zé)接入層開(kāi)發(fā)的同事們會(huì)定期更新證書(shū),負(fù)責(zé)幫忙做 HTTPS 的 RSA 管理。而且這些證書(shū)都是由正規(guī)權(quán)威 CA 機(jī)構(gòu)簽發(fā)的,普遍的客戶(hù)端設(shè)備上都預(yù)置了對(duì)應(yīng)的根證書(shū)。

如果是個(gè)人,一般沒(méi)有條件負(fù)擔(dān) HTTPS 證書(shū)費(fèi)用,因此可以選擇自己簽發(fā)自簽證書(shū),或者到免費(fèi)的證書(shū)簽發(fā)機(jī)構(gòu)申請(qǐng)證書(shū)。但是這類(lèi)證書(shū)要求在客戶(hù)端上同步安裝對(duì)應(yīng)的根證書(shū)。

4. 問(wèn)題:https 項(xiàng)目中,客戶(hù)端的根證書(shū)要提前安裝嗎?

上一個(gè)問(wèn)題中已經(jīng)提到了:

  • 如果是正規(guī)權(quán)威 CA 機(jī)構(gòu)簽發(fā)的證書(shū),一般不需要提前安裝;
  • 如果是私人簽發(fā)的證書(shū),需要提前安裝。

但是,筆者在邊緣計(jì)算設(shè)備上開(kāi)發(fā)時(shí)發(fā)現(xiàn),比如攝像頭這類(lèi)的“tinny os”上,是一個(gè)“閹割”版本的 Linux 系統(tǒng),因此沒(méi)有安裝任何根證書(shū)。在這類(lèi)設(shè)備上做 https 通信,一定需要提前安裝根證書(shū)才行。

責(zé)任編輯:趙寧寧 來(lái)源: 騰訊技術(shù)工程
相關(guān)推薦

2022-07-26 00:00:22

HTAP系統(tǒng)數(shù)據(jù)庫(kù)

2014-04-17 16:42:03

DevOps

2019-09-16 08:40:42

2014-11-28 10:31:07

Hybrid APP

2023-03-16 10:49:55

2021-01-15 07:44:21

SQL注入攻擊黑客

2021-11-09 09:48:13

Logging python模塊

2025-01-03 08:09:15

2024-02-02 08:50:20

Node.js元數(shù)據(jù)自動(dòng)化

2017-10-18 22:01:12

2023-10-24 08:53:24

FutureTas并發(fā)編程

2012-05-31 09:56:54

云安全

2015-07-31 10:35:18

實(shí)時(shí)計(jì)算

2022-12-12 08:46:11

2019-11-06 09:52:01

JavaScript單線(xiàn)程非阻塞

2022-03-14 07:53:27

ELTETL大數(shù)據(jù)

2023-05-10 11:07:18

2016-01-13 10:34:57

物聯(lián)網(wǎng)物聯(lián)網(wǎng)技術(shù)

2018-01-06 10:38:51

Ping抓包 ICMP協(xié)議

2010-08-16 14:07:44

盒模型marginpadding
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)