信息的保密和認證(3) ————證書,證書,到處是證書!

話說本幽靈在以前的科普里提到過N次數字證書[1]和中間人攻擊[2]這一問題,但一直都沒能說說這數字證書到底是什麼玩意,這次咱們就好好聊聊吧!

首先,諸位應該都清楚了,要想建立加密連接就要經歷這樣一些步驟:先是通信雙方身份認證,然後再協商密鑰,最後開始交換數據。

那麼就要解決身份認證和密鑰協商的問題了。應該會沒人天真到認為一個域名就能完成身份認證吧?DNS不靠譜這點翻牆黨應該是最清楚的了,GFW的主要技能之一DNS污染就是利用了DNS的不可靠[3]。

“啊,這麼說,數字證書應該就是拿來完成身份認證的吧?”沒錯!至於具體機制待會再聊,現在讓我們繼續考慮密鑰協商的問題吧。

可不可以讓通信雙方事先在線下協商好密鑰,然後再進行線上通信呢?當然是可以的,但是對於網站而言,這太不現實了,請自行想像每一個訪問google的人都要先給google的工作人員打電話商量密鑰的場景:)

所以就只能這麼辦了:通過非對稱加密算法完成密鑰交換。具體來說,網站向客戶端出示公鑰,然後客戶端用公鑰加密會話密鑰(或者用於生成會話密鑰的偽隨機參數)傳遞給網站,在這過程中第三方因為沒有私鑰而無法得知傳遞內容,網站接收到之後就用私鑰解密,然後開始加密通信。

“看起來好像都不需要身份認證了,第三方又沒有私鑰。”想得美,第三方雖然無法解密內容,但是可以這麼做:第三方截取客戶端和網站之間的通信,然後在客戶端面前裝成網站,把自己的公鑰出示給客戶端;客戶端不知中計,就用第三方的公鑰進行了密鑰交換,第三方自然是解密內容無壓力了,然後就能得知此後所有會話內容。對於網站,第三方又同時裝作客戶端建立加密通信,就像一個代理一樣代理了所有通信內容,這樣中間人攻擊就成功展開了!

我們看到,中間人攻擊成功的關鍵就在於讓客戶端認為第三方的公鑰是網站的。也就是說,只要找到一個辦法讓第三方無法把自己的公鑰說成是網站的公鑰,那麼客戶端和網站就能安全通信了。

而數字證書正是為此而生的!簡單來說,數字證書把證書機構(CA,Certfication Authority)的數字簽名[4]和網站公鑰綁定在了一起,證書機構用自己的私鑰加密了此證書的散列值(就是簽名)[5],加密後的密碼塊和散列值一起被鑲嵌到證書上;客戶端接收到證書時就用證書機構的公鑰解密,再將結果和證書上的散列值比對,如果匹配就說明證書沒問題,網站是真的,反之就終止通信。事實上不僅僅是網站,很多軟件的安裝程序也帶有數字證書,此時就是操作系統進行認證。

這裡就順便說一下win系統自帶的依據數字證書的防篡改系統是怎麼回事:每次用戶右鍵屬性查看數字簽名的時候,系統就會自動計算軟件的散列值,然後比對附在軟件上和數字證書綁定在一起的散列值(這個值是被證書頒發機構的私鑰加密了的,要用公鑰進行解密才能看到),如果匹配成功就說明軟件沒有被篡改,顯示“此數字簽名正常”,否則就顯示數字簽名不正常。

不管怎麼說,這下子第三方就沒有辦法了:不知道證書機構的私鑰,無法偽造出有效證書來了,也就沒法進行中間人攻擊了。

那麼接下來又有一個問題:需要多少個證書頒發機構?以及,誰來當這些證書頒發機構?

很明顯不能只有一個或幾個證書頒發機構:假如是這樣,那麼當其中一個證書頒發機構的私鑰洩漏(被黑客偷走等),那麼就會出現非常嚴重的後果,大部分網站(使用對應證書的)都會面臨中間人攻擊的風險,特別是很多時候私鑰洩漏都是一段時間之後才被發現,那麼……後果可想而知。

“那麼就讓每個網站都自簽發證書,然後用戶訪問的時候自行導入好了!”笨蛋,如果是這樣,那麼用戶體驗會有多差勁?每個用戶第一次訪問網站的時候都要先學會忽略那該死的提示,進入不知是不是釣魚的網站,然後再找到證書下載鏈接,計算並比對散列值(事實上大部分網站都不會提供散列值,也就是說沒法確定這證書有沒有被篡改了),再安裝證書(如果是firefox,那麼還得自行手動導入證書)……真是煩死人無極限啊!

事實上,現在的解決方案是PKI(Public Key Infrastructure),一種等級制的證書信任體系:舉個例子,客戶端A想要訪問網站B,然後網站B出示了證書C,由證書機構D頒發;但是A根本就不知道D是不是合法的證書頒發機構,那麼,A就去根據C上面的說明找到了D的上級,也就是RA(Regional Authority)E,然後E說了:“你看,我這裡有D的公鑰,D是被我信任的合法機構”(C把從E那裡得到的證書出示給A,證書上包含了C的公鑰,用E的公鑰解密即可得到);如果說A都無法確定E是不是合法的證書頒發機構,那麼就接著根據E的說明去找Root(根證書頒發機構)F,然後F說:“放心,我這裡有E的公鑰,E是被我信任的合法證書頒發機構”(E把從F那裡得到的證書出示給A,證書上包含了E的公鑰,用F的公鑰解密即可得到)。

也就是說,在這裡證書機構D,E和F組成了一條信任鏈(chain of trust)。那麼該去哪裡確認根證書頒發機構是否是合法機構呢?事實上,PKI體系假設客戶端一定知道所有現存的合法根證書頒發機構,而這一點是通過瀏覽器實現的:firefox有自己的一套數字證書信任體系,預置了幾百個默認信任的證書;而IE和Chrome則是跟著操作系統走,操作系統內置了默認信任的證書。根證書頒發機構有很多,有些是免費的,大部分是盈利的,不管怎麼說,這樣一來雞蛋就被分散在不同的籃子裡了。

現在,就讓我們一起看看一個具體例子吧。現在通用證書標準是X.509[6],以www.torproject.org的證書為例,一起來看一下具體結構:

首先是版本,版本3代表著使用的是X.509標準的第三個版本;

然後是序列號:09:48:B1:A9:3B:25:1D:0D:B1:05:10:59:E2:C2:68:0A,序列號和證書頒發機構名合起來可以唯一性標定一個證書;

再就是證書籤名算法:SHA-256,前面提到過了,標出證書使用了哪個散列算法;

接著是頒發者,寫了證書頒發機構的詳細信息:
CN = DigiCert SHA2 High Assurance Server CA
OU = www.digicert.com
O = DigiCert Inc
C = US

Snap+2015-03-04+at+18.45.17[1]
下面的有效性說明了證書的有效期限(你不能指望一個證書管一輩子);

然後是使用者,標出了使用者的詳細信息:
CN = *.torproject.org
O = “The Tor Project, Inc.”
L = Walpole
ST = Massachusetts
C = US

接下來是用者公鑰算法和公鑰,建立TLS連接時密鑰交換過程使用的就是這個公鑰(2048位的RSA,用16進製表示);

最後是證書籤名值,也就是前面提到的嵌在證書裡的散列值,用於比對,用16進製表示;

最上面的證書結構就是信任鏈,而可能有人注意到了擴展部分,我想說明一下其中的CRL(Certficate Revocation List):這些證書都不是永久的,有些到期就會被吊銷,還有些因為私鑰洩漏或者沒錢續費之類的原因會被提前吊銷,而每個證書頒發機構都有自己的證書吊銷列表,這些CRL就直接被嵌在證書裡,每次認證的時候都順便訪問一下,看看這證書是否還有效。

說實在的,我對於PKI體系很不滿意:PKI體系過於依賴那些大型證書頒發機構了,特別是根證書頒發機構,有一些根證書頒發機構是各國的NIC(Network Information Center),聽上去沒有問題,不過呢,我想說的是天朝的CNNIC也是根證書頒發機構……

啊,想到了吧?天朝這種流氓國家的流氓機構怎麼有資格當一個根證書頒發機構?CNNIC這貨隨隨便便就能和GFW一起製作一些假冒的證書,然後再把它們都信任了,這下可好了,想對誰中間人攻擊就能對誰中間人攻擊了!具體怎麼回事情我已經在以前的科普[2]裡仔細說過了,這裡就不再重複,總之不能信任天朝的證書!

除此之外,證書頒發機構大部分是盈利的,也就是說他們會被收買,特別是被政府收買,或者也可能被政府的黑客攻擊,這已經是有過先例了[7]。不過,現階段也沒有更好的證書體繫了:(

提到了這麼多次加密算法,但是卻沒能和諸位聊聊密碼學,真是不應該啊。下一篇就聊聊密碼學吧!

科普文鏈接集合:https://plus.google.com/109790703964908675921/posts/TpdEExwyrVj

參考資料:

1,數字證書及CA的掃盲介紹https://plus.google.com/109790703964908675921/posts/3o9x3fpN2CB

2,SSL/TLS的原理以及互聯網究竟是如何工作的(4)
————中間人攻擊,當心!
https://plus.google.com/109790703964908675921/posts/3U3iMGDNZiB

3,GFW的工作原理(2)
————不靠譜的DNS,總是被鑽空子
https://plus.google.com/109790703964908675921/posts/Wqz2qrXdyqs

4,信息的保密和認證(1)
——數字簽名是怎麼回事?
https://plus.google.com/109790703964908675921/posts/fuKwSFikxei

5,信息的保密和認證(2)
————不能被篡改!
https://plus.google.com/109790703964908675921/posts/M6u1HB1sSix

6,https://en.wikipedia.org/wiki/X.509

7,https://www.autistici.org/en/ssl.html

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *