域名預(yù)訂/競(jìng)價(jià),好“米”不錯(cuò)過(guò)
1 前言
百度已經(jīng)于近日上線了全站 HTTPS 的安全搜索,默認(rèn)會(huì)將 HTTP 請(qǐng)求跳轉(zhuǎn)成 HTTPS。本文重點(diǎn)介紹 HTTPS 協(xié)議, 并簡(jiǎn)單介紹部署全站 HTTPS 的意義。
2 HTTPS 協(xié)議概述
HTTPS 可以認(rèn)為是 HTTP + TLS。HTTP 協(xié)議大家耳熟能詳了,目前大部分 WEB 應(yīng)用和網(wǎng)站都是使用 HTTP 協(xié)議傳輸?shù)摹?/p>
TLS 是傳輸層加密協(xié)議,它的前身是 SSL 協(xié)議,最早由 netscape 公司于 1995 年發(fā)布,1999 年經(jīng)過(guò) IETF 討論和規(guī)范后,改名為 TLS。如果沒(méi)有特別說(shuō)明,SSL 和 TLS 說(shuō)的都是同一個(gè)協(xié)議。
HTTP 和 TLS 在協(xié)議層的位置以及 TLS 協(xié)議的組成如下圖:
圖 1 TLS 協(xié)議格式
TLS 協(xié)議主要有五部分:應(yīng)用數(shù)據(jù)層協(xié)議,握手協(xié)議,報(bào)警協(xié)議,加密消息確認(rèn)協(xié)議,心跳協(xié)議。
TLS 協(xié)議本身又是由 record 協(xié)議傳輸?shù)?,record 協(xié)議的格式如上圖最右所示。
目前常用的 HTTP 協(xié)議是 HTTP1.1,常用的 TLS 協(xié)議版本有如下幾個(gè):TLS1.2, TLS1.1, TLS1.0 和 SSL3.0。其中 SSL3.0 由于 POODLE 攻擊已經(jīng)被證明不安全,但統(tǒng)計(jì)發(fā)現(xiàn)依然有不到 1% 的瀏覽器使用 SSL3.0。TLS1.0 也存在部分安全漏洞,比如 RC4 和 BEAST 攻擊。
TLS1.2 和 TLS1.1 暫時(shí)沒(méi)有已知的安全漏洞,比較安全,同時(shí)有大量擴(kuò)展提升速度和性能,推薦大家使用。
需要關(guān)注一點(diǎn)的就是 TLS1.3 將會(huì)是 TLS 協(xié)議一個(gè)非常重大的改革。不管是安全性還是用戶訪問(wèn)速度都會(huì)有質(zhì)的提升。不過(guò)目前沒(méi)有明確的發(fā)布時(shí)間。
同時(shí) HTTP2 也已經(jīng)正式定稿,這個(gè)由 SPDY 協(xié)議演化而來(lái)的協(xié)議相比 HTTP1.1 又是一個(gè)非常重大的變動(dòng),能夠明顯提升應(yīng)用層數(shù)據(jù)的傳輸效率。
3 HTTPS 功能介紹
百度使用 HTTPS 協(xié)議主要是為了保護(hù)用戶隱私,防止流量劫持。
HTTP 本身是明文傳輸?shù)模瑳](méi)有經(jīng)過(guò)任何安全處理。例如用戶在百度搜索了一個(gè)關(guān)鍵字,比如“蘋果手機(jī)”,中間者完全能夠查看到這個(gè)信息,并且有可能打電話過(guò)來(lái)騷擾用戶。也有一些用戶投訴使用百度時(shí),發(fā)現(xiàn)首頁(yè)或者結(jié)果頁(yè)面浮了一個(gè)很長(zhǎng)很大的廣告,這也肯定是中間者往頁(yè)面插的廣告內(nèi)容。如果劫持技術(shù)比較低劣的話,用戶甚至無(wú)法訪問(wèn)百度。
這里提到的中間者主要指一些網(wǎng)絡(luò)節(jié)點(diǎn),是用戶數(shù)據(jù)在瀏覽器和百度服務(wù)器中間傳輸必須要經(jīng)過(guò)的節(jié)點(diǎn)。比如 WIFI 熱點(diǎn),路由器,防火墻,反向代理,緩存服務(wù)器等。
在 HTTP 協(xié)議下,中間者可以隨意嗅探用戶搜索內(nèi)容,竊取隱私甚至篡改網(wǎng)頁(yè)。不過(guò) HTTPS 是這些劫持行為的克星,能夠完全有效地防御。
總體來(lái)說(shuō),HTTPS 協(xié)議提供了三個(gè)強(qiáng)大的功能來(lái)對(duì)抗上述的劫持行為:
1、內(nèi)容加密。瀏覽器到百度服務(wù)器的內(nèi)容都是以加密形式傳輸,中間者無(wú)法直接查看原始內(nèi)容。
2、身份認(rèn)證。保證用戶訪問(wèn)的是百度服務(wù),即使被 DNS 劫持到了第三方站點(diǎn),也會(huì)提醒用戶沒(méi)有訪問(wèn)百度服務(wù),有可能被劫持
3、數(shù)據(jù)完整性。防止內(nèi)容被第三方冒充或者篡改。
那 HTTPS 是如何做到上述三點(diǎn)的呢?下面從原理角度介紹一下。
4 HTTPS 原理介紹
4.1 內(nèi)容加密
加密算法一般分為兩種,對(duì)稱加密和非對(duì)稱加密。所謂對(duì)稱加密(也叫密鑰加密)就是指加密和解密使用的是相同的密鑰。而非對(duì)稱加密(也叫公鑰加密)就是指加密和解密使用了不同的密鑰。
圖 2 對(duì)稱加密
圖 3 非對(duì)稱加密
對(duì)稱內(nèi)容加密強(qiáng)度非常高,一般破解不了。但存在一個(gè)很大的問(wèn)題就是無(wú)法安全地生成和保管密鑰。假如客戶端軟件和服務(wù)器之間每次會(huì)話都使用固定的,相同的密鑰加密和解密,肯定存在很大的安全隱患。如果有人從客戶端端獲取到了對(duì)稱密鑰,整個(gè)內(nèi)容就不存在安全性了,而且管理海量的客戶端密鑰也是一件很復(fù)雜的事情。
非對(duì)稱加密主要用于密鑰交換(也叫密鑰協(xié)商),能夠很好地解決這個(gè)問(wèn)題。瀏覽器和服務(wù)器每次新建會(huì)話時(shí)都使用非對(duì)稱密鑰交換算法協(xié)商出對(duì)稱密鑰,使用這些對(duì)稱密鑰完成應(yīng)用數(shù)據(jù)的加解密和驗(yàn)證,整個(gè)會(huì)話過(guò)程中的密鑰只在內(nèi)存中生成和保存,而且每個(gè)會(huì)話的對(duì)稱密鑰都不相同(除非會(huì)話復(fù)用),中間者無(wú)法竊取。
非對(duì)稱密鑰交換很安全,但同時(shí)也是 HTTPS 性能和速度嚴(yán)重降低的“罪魁禍?zhǔn)?rdquo;。想要知道 HTTPS 為什么影響速度,為什么消耗資源,就一定要理解非對(duì)稱密鑰交換的整個(gè)過(guò)程。
下面重點(diǎn)介紹一下非對(duì)稱密鑰交換的數(shù)學(xué)原理及在 TLS 握手過(guò)程中的應(yīng)用。
4.1.1 非對(duì)稱密鑰交換
在非對(duì)稱密鑰交換算法出現(xiàn)以前,對(duì)稱加密一個(gè)很大的問(wèn)題就是不知道如何安全生成和保管密鑰。非對(duì)稱密鑰交換過(guò)程主要就是為了解決這個(gè)問(wèn)題,使得對(duì)稱密鑰的生成和使用更加安全。
密鑰交換算法本身非常復(fù)雜,密鑰交換過(guò)程涉及到隨機(jī)數(shù)生成,模指數(shù)運(yùn)算,空白補(bǔ)齊,加密,簽名等操作。
常見(jiàn)的密鑰交換算法有 RSA,ECDHE,DH,DHE 等算法。它們的特性如下:
RSA:算法實(shí)現(xiàn)簡(jiǎn)單,誕生于 1977 年,歷史悠久,經(jīng)過(guò)了長(zhǎng)時(shí)間的破解測(cè)試,安全性高。缺點(diǎn)就是需要比較大的素?cái)?shù)(目前常用的是 2048 位)來(lái)保證安全強(qiáng)度,很消耗 CPU 運(yùn)算資源。RSA 是目前唯一一個(gè)既能用于密鑰交換又能用于證書簽名的算法。
DH:diffie-hellman 密鑰交換算法,誕生時(shí)間比較早(1977 年),但是 1999 年才公開(kāi)。缺點(diǎn)是比較消耗 CPU 性能。
ECDHE:使用橢圓曲線(ECC)的 DH 算法,優(yōu)點(diǎn)是能用較小的素?cái)?shù)(256 位)實(shí)現(xiàn) RSA 相同的安全等級(jí)。缺點(diǎn)是算法實(shí)現(xiàn)復(fù)雜,用于密鑰交換的歷史不長(zhǎng),沒(méi)有經(jīng)過(guò)長(zhǎng)時(shí)間的安全攻擊測(cè)試。
ECDH:不支持 PFS,安全性低,同時(shí)無(wú)法實(shí)現(xiàn) false start。
DHE:不支持 ECC。非常消耗 CPU 資源。
建議優(yōu)先支持 RSA 和 ECDH_RSA 密鑰交換算法。原因是:
1、ECDHE 支持 ECC 加速,計(jì)算速度更快。支持 PFS,更加安全。支持 false start,用戶訪問(wèn)速度更快。
2、目前還有至少 20% 以上的客戶端不支持 ECDHE,我們推薦使用 RSA 而不是 DH 或者 DHE,因?yàn)?DH 系列算法非常消耗 CPU(相當(dāng)于要做兩次 RSA 計(jì)算)。
需要注意通常所說(shuō)的 ECDHE 密鑰交換默認(rèn)都是指 ECDHE_RSA,使用 ECDHE 生成 DH 算法所需的公私鑰,然后使用 RSA 算法進(jìn)行簽名最后再計(jì)算得出對(duì)稱密鑰。
非對(duì)稱加密相比對(duì)稱加密更加安全,但也存在兩個(gè)明顯缺點(diǎn):
1、CPU 計(jì)算資源消耗非常大。一次完全 TLS 握手,密鑰交換時(shí)的非對(duì)稱解密計(jì)算量占整個(gè)握手過(guò)程的 90% 以上。而對(duì)稱加密的計(jì)算量只相當(dāng)于非對(duì)稱加密的 0.1%,如果應(yīng)用層數(shù)據(jù)也使用非對(duì)稱加解密,性能開(kāi)銷太大,無(wú)法承受。
2、非對(duì)稱加密算法對(duì)加密內(nèi)容的長(zhǎng)度有限制,不能超過(guò)公鑰長(zhǎng)度。比如現(xiàn)在常用的公鑰長(zhǎng)度是 2048 位,意味著待加密內(nèi)容不能超過(guò) 256 個(gè)字節(jié)。
所以公鑰加密目前只能用來(lái)作密鑰交換或者內(nèi)容簽名,不適合用來(lái)做應(yīng)用層傳輸內(nèi)容的加解密。
非對(duì)稱密鑰交換算法是整個(gè) HTTPS 得以安全的基石,充分理解非對(duì)稱密鑰交換算法是理解 HTTPS 協(xié)議和功能的關(guān)鍵。
下面分別通俗地介紹一下 RSA 和 ECDHE 在密鑰交換過(guò)程中的應(yīng)用。
4.1.1.1 RSA 密鑰協(xié)商
4.1.1.1.1 RSA 算法介紹
RSA 算法的安全性是建立在乘法不可逆或者大數(shù)因子很難分解的基礎(chǔ)上。RSA 的推導(dǎo)和實(shí)現(xiàn)涉及到了歐拉函數(shù)和費(fèi)馬定理及模反元素的概念,有興趣的讀者可以自行百度。
RSA 算法是統(tǒng)治世界的最重要算法之一,而且從目前來(lái)看,RSA 也是 HTTPS 體系中最重要的算法,沒(méi)有之一。
RSA 的計(jì)算步驟如下:
1、隨機(jī)挑選兩個(gè)質(zhì)數(shù) p, q,假設(shè) p = 13, q = 19。 n = p * q = 13 * 19 = 247;
2、∅(n) 表示與整數(shù) n 互質(zhì)數(shù)的個(gè)數(shù)。如果 n 等于兩個(gè)質(zhì)數(shù)的積,則∅(n)=(p-1)(q-1) 挑選一個(gè)數(shù) e,滿足 1< e <∅(n) 并且 e 與互質(zhì),假設(shè) e = 17;
3、計(jì)算 e 關(guān)于 n 的模反元素, ed=1 mod ∅(n) , 由 e = 17 ,∅(n) =216 可得 d = 89;
4、求出了 e,和 d,假設(shè)明文 m = 135,密文用 c 表示。
那么加解密計(jì)算如下:
實(shí)際應(yīng)用中,(n,e) 組成了公鑰對(duì),(n,d)組成了私鑰對(duì),其中 n 和 d 都是一個(gè)接近 22048的大數(shù)。即使現(xiàn)在性能很強(qiáng)的 CPU,想要計(jì)算 m≡c^d mod(n),也需要消耗比較大的計(jì)算資源和時(shí)間。
公鑰對(duì) (n, e) 一般都注冊(cè)到了證書里,任何人都能直接查看,比如百度證書的公鑰對(duì)如下圖,其中最末 6 個(gè)數(shù)字(010001)換算成 10 進(jìn)制就是 65537,也就是公鑰對(duì)中的 e。e 取值比較小的好處有兩個(gè):
1、由 c=m^e mod(n) 可知,e 較小,客戶端 CPU 計(jì)算消耗的資源較少。
2、加大 server 端的破解難度。e 比較小,私鑰對(duì)中的 d 必然會(huì)非常大。所以 d 的取值空間也就非常大,增加了破解難度。
那為什么 (n,e) 能做為公鑰公開(kāi),甚至大家都能直接從證書中查看到,這樣安全嗎?分析如下:
由于 ed≡1 mod ∅(n),知道了 e 和 n,想要求出私鑰 d,就必須知道∅(n)。而∅(n)=(p-1)*(q-1),必須計(jì)算出 p 和 q 才能確定私鑰 d。但是當(dāng) n 大到一定程度時(shí)(比如接近 2^2048),即使現(xiàn)在最快的 CPU 也無(wú)法進(jìn)行這個(gè)因式分解,即無(wú)法知道 n 是由哪個(gè)數(shù) p 和 q 乘出來(lái)的。所以就算知道了公鑰,整個(gè)加解密過(guò)程還是非常安全的。
圖 5 百度 HTTPS 證書公鑰
4.1.1.1.2 握手過(guò)程中的 RSA 密鑰協(xié)商
介紹完了 RSA 的原理,那最終會(huì)話所需要的對(duì)稱密鑰是如何生成的呢?跟 RSA 有什么關(guān)系?
以 TLS1.2 為例簡(jiǎn)單描述一下,省略跟密鑰交換無(wú)關(guān)的握手消息。過(guò)程如下:
1、瀏覽器發(fā)送 client_hello,包含一個(gè)隨機(jī)數(shù) random1。
2、服務(wù)端回復(fù) server_hello,包含一個(gè)隨機(jī)數(shù) random2,同時(shí)回復(fù) certificate,攜帶了證書公鑰 P。
3、瀏覽器接收到 random2 之后就能夠生成 premaster_secrect 以及 master_secrect。其中 premaster_secret 長(zhǎng)度為 48 個(gè)字節(jié),前 2 個(gè)字節(jié)是協(xié)議版本號(hào),剩下的 46 個(gè)字節(jié)填充一個(gè)隨機(jī)數(shù)。結(jié)構(gòu)如下:
Struct {byte Version[2];bute random[46];}
master secrect 的生成算法簡(jiǎn)述如下:
Master_key = PRF(premaster_secret, “master secrect”, 隨機(jī)數(shù)1+隨機(jī)數(shù)2)其中 PRF 是一個(gè)隨機(jī)函數(shù),定義如下:PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
從上式可以看出,把 premaster_key 賦值給 secret,”master key”賦值給 label,瀏覽器和服務(wù)器端的兩個(gè)隨機(jī)數(shù)做種子就能確定地求出一個(gè) 48 位長(zhǎng)的隨機(jī)數(shù)。
而 master secrect 包含了六部分內(nèi)容,分別是用于校驗(yàn)內(nèi)容一致性的密鑰,用于對(duì)稱內(nèi)容加解密的密鑰,以及初始化向量(用于 CBC 模式),客戶端和服務(wù)端各一份。
至此,瀏覽器側(cè)的密鑰已經(jīng)完成協(xié)商。
4、瀏覽器使用證書公鑰 P 將 premaster_secrect 加密后發(fā)送給服務(wù)器。
5、服務(wù)端使用私鑰解密得到 premaster_secrect。又由于服務(wù)端之前就收到了隨機(jī)數(shù) 1,所以服務(wù)端根據(jù)相同的生成算法,在相同的輸入?yún)?shù)下,求出了相同的 master secrect。
RSA 密鑰協(xié)商握手過(guò)程圖示如下:
圖 6 RSA 密鑰協(xié)商過(guò)程
可以看出,密鑰協(xié)商過(guò)程需要 2 個(gè) RTT,這也是 HTTPS 慢的一個(gè)重要原因。而 RSA 發(fā)揮的關(guān)鍵作用就是對(duì) premaster_secrect 進(jìn)行了加密和解密。中間者不可能破解 RSA 算法,也就不可能知道 premaster_secrect,從而保證了密鑰協(xié)商過(guò)程的安全性。
4.1.1.2 ECDHE 密鑰協(xié)商
4.1.1.2.1 DH 與 ECC 算法原理
ECDHE 算法實(shí)現(xiàn)要復(fù)雜很多,主要分為兩部分:diffie-hellman 算法(簡(jiǎn)稱為 DH)及 ECC(橢圓曲線算術(shù))。他們的安全性都是建立在離散對(duì)數(shù)計(jì)算很困難的基礎(chǔ)上。
簡(jiǎn)單介紹一下 dh 算法的實(shí)現(xiàn),先介紹兩個(gè)基本概念:
本原根:如果整數(shù) a 是素?cái)?shù) p 的本原根,則 a, a^2, …, a^(p-1) 在 mod p 下都不相同。
離散對(duì)數(shù):對(duì)任意整數(shù) b 和素?cái)?shù) p 的本原根 a,存在唯一的指數(shù) i 滿足:
b ≡ a^i mod p (0≤i≤p-1)
則稱 i 是 b 的以 a 為底的模 p 的離散對(duì)數(shù)。
理解這兩個(gè)概念,dh 算法就非常簡(jiǎn)單了,示例如下:
假設(shè) client 和 server 需要協(xié)商密鑰,p=2579,則本原根 a = 2。
1、Client 選擇隨機(jī)數(shù) Kc = 123 做為自己的私鑰,計(jì)算 Yc = a^Kc mod p = 2^123 mod 2579 = 2400,把 Yc 作為公鑰發(fā)送給 server。
2、Server 選擇隨機(jī)數(shù) Ks = 293 作為私鑰,計(jì)算 Ys = a^Ks mod p = s^293 mod 2579 = 968,把 Ys 作為公鑰發(fā)送給 client。
3、Client 計(jì)算共享密鑰:secrect = Ys^Kc mod (p) = 968^123 mod(2579) = 434
4、Server 計(jì)算共享密鑰:secrect = Yc^Ks mod(p) =2400^293 mod(2579) =434
上述公式中的 Ys,Yc,P, a, 都是公開(kāi)信息,可以被中間者查看,只有 Ks,Kc 作為私鑰沒(méi)有公開(kāi),當(dāng)私鑰較小時(shí),通過(guò)窮舉攻擊能夠計(jì)算出共享密鑰,但是當(dāng)私鑰非常大時(shí),窮舉攻擊肯定是不可行的。
DH 算法有一個(gè)比較大的缺陷就是需要提供足夠大的私鑰來(lái)保證安全性,所以比較消耗 CPU 計(jì)算資源。ECC 橢圓曲線算術(shù)能夠很好的解決這個(gè)問(wèn)題,224 位的密鑰長(zhǎng)度就能達(dá)到 RSA2048 位的安全強(qiáng)度。
ECC 的曲線公式描述的其實(shí)不是橢圓,只是跟橢圓曲線周長(zhǎng)公式形似才叫橢圓曲線加密算術(shù)。ECC 涉及到了有限域、群等近世代數(shù)的多個(gè)概念,就不做詳細(xì)介紹了。
ECC 安全性依賴于這樣一個(gè)事實(shí):
P = kQ, 已知 k, Q 求出 P 相對(duì)簡(jiǎn)單,但是已知 P 和 Q 求出 k 卻非常困難。
上式看起來(lái)非常簡(jiǎn)單,但有如下約束條件:
1、Q 是一個(gè)非常大的質(zhì)數(shù),p, k, q 都是橢圓曲線有限域上的離散點(diǎn)。
2、有限域定義了自己的加法和乘法法則,即使 kQ 的運(yùn)算也非常復(fù)雜。
ECC 應(yīng)用于 Diffie-Hellman 密鑰交換過(guò)程如下:
1、定義一個(gè)滿足橢圓方程的有限域,即挑選 p, a, b 滿足如下方程:
y^2 mod p = (x^3+ax +b) mod p
2、挑選基點(diǎn) G = (x, y),G 的階為 n。n 為滿足 nG = 0 的最小正整數(shù)。
3、Client 選擇私鑰 Kc (0
4、server 選擇私鑰 Ks 并產(chǎn)生公鑰 Ys =Ks*G
5、client 計(jì)算共享密鑰 K = Kc*Ys ,server 端計(jì)算共享密鑰 Ks*Yc ,這兩者的結(jié)果是一樣的,因?yàn)椋?/p>
Kc*Ys = Kc*(Ks*G) = Ks*(Kc*G) = Ks*Yc
由上面描述可知,只要確定 p, a, b 就能確定一條有限域上的橢圓曲線,由于不是所有的橢圓曲線都能夠用于加密,所以 p, a, b 的選取非常講究,直接關(guān)系曲線的安全性和計(jì)算速度。
Openssl 實(shí)現(xiàn)的,也是 FIPS 推薦的 256 位素?cái)?shù)域上的橢圓曲線參數(shù)定義如下:
質(zhì)數(shù) p = 115792089210356248762697446949407573530086143415290314195533631308867097853951 階 n = 115792089210356248762697446949407573529996955224135760342422259061068512044369SEED = c49d3608 86e70493 6a6678e1 139d26b7 819f7e90c = 7efba166 2985be94 03cb055c 75d4f7e0 ce8d84a9 c5114abcaf317768 0104fa0d 橢圓曲線的系數(shù) a = 0 橢圓曲線的系統(tǒng) b = 5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f63bce3c3e 27d2604b 基點(diǎn) G x = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0f4a13945 d898c296 基點(diǎn) G y = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ececbb64068 37bf51f5
4.1.1.2.2 握手過(guò)程中的 ECDHE 密鑰協(xié)商
簡(jiǎn)單介紹了 ECC 和 DH 算法的數(shù)學(xué)原理,我們看下 ECDHE 在 TLS 握手過(guò)程中的應(yīng)用。
相比 RSA,ECDHE 需要多發(fā)送一個(gè) server_key_exchange 的握手消息才能完成密鑰協(xié)商。
同樣以 TLS1.2 為例,簡(jiǎn)單描述一下過(guò)程:
1、瀏覽器發(fā)送 client_hello,包含一個(gè)隨機(jī)數(shù) random1,同時(shí)需要有 2 個(gè)擴(kuò)展:
a) Elliptic_curves:客戶端支持的曲線類型和有限域參數(shù)?,F(xiàn)在使用最多的是 256 位的素?cái)?shù)域,參數(shù)定義如上節(jié)所述。
b) Ec_point_formats:支持的曲線點(diǎn)格式,默認(rèn)都是 uncompressed。
2、服務(wù)端回復(fù) server_hello,包含一個(gè)隨機(jī)數(shù) random2 及 ECC 擴(kuò)展。
3、服務(wù)端回復(fù) certificate,攜帶了證書公鑰。
4、服務(wù)端生成 ECDH 臨時(shí)公鑰,同時(shí)回復(fù) server_key_exchange,包含三部分重要內(nèi)容:
a) ECC 相關(guān)的參數(shù)。
b) ECDH 臨時(shí)公鑰。
c) ECC 參數(shù)和公鑰生成的簽名值,用于客戶端校驗(yàn)。
5、瀏覽器接收 server_key_exchange 之后,使用證書公鑰進(jìn)行簽名解密和校驗(yàn),獲取服務(wù)器端的 ECDH 臨時(shí)公鑰,生成會(huì)話所需要的共享密鑰。
至此,瀏覽器端完成了密鑰協(xié)商。
6、瀏覽器生成 ECDH 臨時(shí)公鑰和 client_key_exchange 消息,跟 RSA 密鑰協(xié)商不同的是,這個(gè)消息不需要加密了。
7、服務(wù)器處理 client_key_exchang 消息,獲取客戶端 ECDH 臨時(shí)公鑰。
8、服務(wù)器生成會(huì)話所需要的共享密鑰。
9、Server 端密鑰協(xié)商過(guò)程結(jié)束。
圖示如下:
圖 7 ECDHE 密鑰協(xié)商過(guò)程
4.1.2 對(duì)稱內(nèi)容加密
非對(duì)稱密鑰交換過(guò)程結(jié)束之后就得出了本次會(huì)話需要使用的對(duì)稱密鑰。對(duì)稱加密又分為兩種模式:流式加密和分組加密。流式加密現(xiàn)在常用的就是 RC4,不過(guò) RC4 已經(jīng)不再安全,微軟也建議網(wǎng)站盡量不要使用 RC4 流式加密。
一種新的替代 RC4 的流式加密算法叫 ChaCha20,它是 google 推出的速度更快,更安全的加密算法。目前已經(jīng)被 android 和 chrome 采用,也編譯進(jìn)了 google 的開(kāi)源 openssl 分支 —boring ssl,并且nginx 1.7.4 也支持編譯 boringssl。
分組加密以前常用的模式是 AES-CBC,但是 CBC 已經(jīng)被證明容易遭受BEAST和LUCKY13 攻擊。目前建議使用的分組加密模式是 AES-GCM,不過(guò)它的缺點(diǎn)是計(jì)算量大,性能和電量消耗都比較高,不適用于移動(dòng)電話和平板電腦。
4.2 身份認(rèn)證
身份認(rèn)證主要涉及到 PKI 和數(shù)字證書。通常來(lái)講 PKI(公鑰基礎(chǔ)設(shè)施)包含如下部分:
End entity:終端實(shí)體,可以是一個(gè)終端硬件或者網(wǎng)站。
CA:證書簽發(fā)機(jī)構(gòu)。
RA:證書注冊(cè)及審核機(jī)構(gòu)。比如審查申請(qǐng)網(wǎng)站或者公司的真實(shí)性。
CRL issuer:負(fù)責(zé)證書撤銷列表的發(fā)布和維護(hù)。
Repository:負(fù)責(zé)數(shù)字證書及 CRL 內(nèi)容存儲(chǔ)和分發(fā)。
申請(qǐng)一個(gè)受信任的數(shù)字證書通常有如下流程:
1、終端實(shí)體生成公私鑰和證書請(qǐng)求。
2、RA 檢查實(shí)體的合法性。如果個(gè)人或者小網(wǎng)站,這一步不是必須的。
3、CA 簽發(fā)證書,發(fā)送給申請(qǐng)者。
4、證書更新到 repository,終端后續(xù)從 repository 更新證書,查詢證書狀態(tài)等。
目前百度使用的證書是 X509v3 格式,由如下三個(gè)部分組成:
1、tbsCertificate(to be signed certificate 待簽名證書內(nèi)容),這部分包含了 10 個(gè)要素,分別是版本號(hào),序列號(hào),簽名算法標(biāo)識(shí),發(fā)行者名稱,有效期,證書主體名,證書主體公鑰信息,發(fā)行商唯一標(biāo)識(shí),主體唯一標(biāo)識(shí),擴(kuò)展等。
2、signatureAlgorithm,簽名算法標(biāo)識(shí),指定對(duì) tbsCertificate 進(jìn)行簽名的算法。
3、signaturValue(簽名值),使用 signatureAlgorithm 對(duì) tbsCertificate 進(jìn)行計(jì)算得到簽名值。
數(shù)字證書有兩個(gè)作用:
1、身份授權(quán)。確保瀏覽器訪問(wèn)的網(wǎng)站是經(jīng)過(guò) CA 驗(yàn)證的可信任的網(wǎng)站。
2、分發(fā)公鑰。每個(gè)數(shù)字證書都包含了注冊(cè)者生成的公鑰。在 SSL 握手時(shí)會(huì)通過(guò) certificate 消息傳輸給客戶端。比如前文提到的 RSA 證書公鑰加密及 ECDHE 的簽名都是使用的這個(gè)公鑰。
申請(qǐng)者拿到 CA 的證書并部署在網(wǎng)站服務(wù)器端,那瀏覽器發(fā)起握手接收到證書后,如何確認(rèn)這個(gè)證書就是 CA 簽發(fā)的呢?怎樣避免第三方偽造這個(gè)證書?
答案就是數(shù)字簽名(digital signature)。數(shù)字簽名是證書的防偽標(biāo)簽,目前使用最廣泛的 SHA-RSA 數(shù)字簽名的制作和驗(yàn)證過(guò)程如下:
1、數(shù)字簽名的簽發(fā)。首先是使用哈希函數(shù)對(duì)待簽名內(nèi)容進(jìn)行安全哈希,生成消息摘要,然后使用 CA 自己的私鑰對(duì)消息摘要進(jìn)行加密。
2、數(shù)字簽名的校驗(yàn)。使用 CA 的公鑰解密簽名,然后使用相同的簽名函數(shù)對(duì)待簽名證書內(nèi)容進(jìn)行簽名并和服務(wù)端數(shù)字簽名里的簽名內(nèi)容進(jìn)行比較,如果相同就認(rèn)為校驗(yàn)成功。
圖 8 數(shù)字簽名生成及校驗(yàn)
這里有幾點(diǎn)需要說(shuō)明:
數(shù)字簽名簽發(fā)和校驗(yàn)使用的密鑰對(duì)是 CA 自己的公私密鑰,跟證書申請(qǐng)者提交的公鑰沒(méi)有關(guān)系。 數(shù)字簽名的簽發(fā)過(guò)程跟公鑰加密的過(guò)程剛好相反,即是用私鑰加密,公鑰解密。 現(xiàn)在大的 CA 都會(huì)有證書鏈,證書鏈的好處一是安全,保持根 CA 的私鑰離線使用。第二個(gè)好處是方便部署和撤銷,即如果證書出現(xiàn)問(wèn)題,只需要撤銷相應(yīng)級(jí)別的證書,根證書依然安全。 根 CA 證書都是自簽名,即用自己的公鑰和私鑰完成了簽名的制作和驗(yàn)證。而證書鏈上的證書簽名都是使用上一級(jí)證書的密鑰對(duì)完成簽名和驗(yàn)證的。 怎樣獲取根 CA 和多級(jí) CA 的密鑰對(duì)?它們是否可信?當(dāng)然可信,因?yàn)檫@些廠商跟瀏覽器和操作系統(tǒng)都有合作,它們的公鑰都默認(rèn)裝到了瀏覽器或者操作系統(tǒng)環(huán)境里。比如firefox 就自己維護(hù)了一個(gè)可信任的 CA 列表,而chrome 和 IE 使用的是操作系統(tǒng)的 CA 列表。 4.3 數(shù)據(jù)完整性
這部分內(nèi)容比較好理解,跟平時(shí)的 md5 簽名類似,只不過(guò)安全要求要高很多。openssl 現(xiàn)在使用的完整性校驗(yàn)算法有兩種:MD5 或者 SHA。由于 MD5 在實(shí)際應(yīng)用中存在沖突的可能性比較大,所以盡量別采用 MD5 來(lái)驗(yàn)證內(nèi)容一致性。SHA 也不能使用 SHA0 和 SHA1,中國(guó)山東大學(xué)的王小云教授在 2005 年就宣布破解了 SHA-1 完整版算法。
微軟和 google 都已經(jīng)宣布 16 年及 17 年之后不再支持 sha1 簽名證書。
5 HTTPS 使用成本
HTTPS 目前唯一的問(wèn)題就是它還沒(méi)有得到大規(guī)模應(yīng)用,受到的關(guān)注和研究都比較少。至于使用成本和額外開(kāi)銷,完全不用太過(guò)擔(dān)心。
一般來(lái)講,使用 HTTPS 前大家可能會(huì)非常關(guān)注如下問(wèn)題:
1、證書費(fèi)用以及更新維護(hù)。大家覺(jué)得申請(qǐng)證書很麻煩,證書也很貴,可是證書其實(shí)一點(diǎn)都不貴,便宜的一年幾十塊錢,最多也就幾百。而且現(xiàn)在也有了免費(fèi)的證書機(jī)構(gòu),比如著名的 mozilla 發(fā)起的免費(fèi)證書項(xiàng)目:let’s encrypt()就支持免費(fèi)證書安裝和自動(dòng)更新。這個(gè)項(xiàng)目將于今年中旬投入正式使用。
數(shù)字證書的費(fèi)用其實(shí)也不高,對(duì)于中小網(wǎng)站可以使用便宜甚至免費(fèi)的數(shù)字證書服務(wù)(可能存在安全隱患),像著名的 verisign 公司的證書一般也就幾千到幾萬(wàn)塊一年不等。當(dāng)然如果公司對(duì)證書的需求比較大,定制性要求高,可以建立自己的 CA 站點(diǎn),比如 google,能夠隨意簽發(fā) google 相關(guān)證書。
2、HTTPS 降低用戶訪問(wèn)速度。HTTPS 對(duì)速度會(huì)有一定程度的降低,但是只要經(jīng)過(guò)合理優(yōu)化和部署,HTTPS 對(duì)速度的影響完全可以接受。在很多場(chǎng)景下,HTTPS 速度完全不遜于 HTTP,如果使用 SPDY,HTTPS 的速度甚至還要比 HTTP 快。
大家現(xiàn)在使用百度 HTTPS 安全搜索,有感覺(jué)到慢嗎?
3、HTTPS 消耗 CPU 資源,需要增加大量機(jī)器。前面介紹過(guò)非對(duì)稱密鑰交換,這是消耗 CPU 計(jì)算資源的大戶,此外,對(duì)稱加解密,也需要 CPU 的計(jì)算。
同樣地,只要合理優(yōu)化,HTTPS 的機(jī)器成本也不會(huì)明顯增加。對(duì)于中小網(wǎng)站,完全不需要增加機(jī)器也能滿足性能需求。
6 后記
國(guó)外的大型互聯(lián)網(wǎng)公司很多已經(jīng)啟用了全站 HTTPS,這也是未來(lái)互聯(lián)網(wǎng)的趨勢(shì)。國(guó)內(nèi)的大型互聯(lián)網(wǎng)并沒(méi)有全站部署 HTTPS,只是在一些涉及賬戶或者交易的子頁(yè)面 / 子請(qǐng)求上啟用了 HTTPS。百度搜索首次全站部署 HTTPS,對(duì)國(guó)內(nèi)互聯(lián)網(wǎng)的全站 HTTPS 進(jìn)程必將有著巨大的推動(dòng)作用。
目前互聯(lián)網(wǎng)上關(guān)于 HTTPS 的中文資料比較少,本文就著重介紹了 HTTPS 協(xié)議涉及到的重要知識(shí)點(diǎn)和平時(shí)不太容易理解的盲區(qū),希望能對(duì)大家理解 HTTPS 協(xié)議有幫助。百度 HTTPS 性能優(yōu)化涉及到大量?jī)?nèi)容,從前端頁(yè)面、后端架構(gòu)、協(xié)議特性、加密算法、流量調(diào)度、架構(gòu)和運(yùn)維、安全等方面都做了大量工作。
延伸閱讀:
- HTTPS對(duì)網(wǎng)站性能SEO有哪些影響?
申請(qǐng)創(chuàng)業(yè)報(bào)道,分享創(chuàng)業(yè)好點(diǎn)子。點(diǎn)擊此處,共同探討創(chuàng)業(yè)新機(jī)遇!