從 HTTPS 入門看 X.509、RSA、PKI 到底是什麼?
如果每個東西都要照著教科書來,我們應該會需要寫一個系列文了 XD。
為了方便理解,這邊就僅 我個人 覺得必要的部份來進行說明。
注:雖然前面是這麼說,但還是懇請前輩們多多賜教 Orz
公開金鑰加密(Public-key cryptography)
相對於直觀的對稱式金鑰加密(Symmetric key algorithm),使用同一把鑰匙(key)進行加、解密的動作。
公開金鑰加密(又稱 非對稱式金鑰加密,Asymmetric key algorithm)則會使用 2 把鑰匙來達成同樣的動作。兩兩成對,用這把加密,就用另一把解密(有玩過經典遊戲 Portal 的話可以想像那個畫面)。
舉例來說,常見的情境裡,一位素未謀面的使用者(姑且稱為 Alice),想傳送機密訊息給我(Bob)。為了避免被竊聽,Alice 先到公開的目錄(e.g. FB)拿到我的公開金鑰(Public key)。加密之後再傳送給我。
等等,雖然大家可能不是特別在意,但其實 Alice 跟 Bob 互相通訊,Eve 偷聽,是資訊安全領域常用的假名。由來大概是
A氏 ---> B氏
實在太難唸了,所以乾脆取個名子這樣,而 Eve 則是 eavesdrop(竊聽)的縮寫。 然後我其實不是 Bob(嚴肅臉
收到訊息之後,我(Bob)再使用我的私有金鑰(Private key)解密訊息,變回明文。
有趣的是,整個過程也可以反過來!
乍聽之下似乎不是很特別,不過換個方式思考:
除了
Bob
的 私有金鑰(Private key
)之外,沒有任何東西能產生 “剛好” 可以被這一把公開金鑰(Public key
)解密的訊息
也就是說,我們可以用這種方法來 證明自己真的是 Bob ,這也是數位簽章(Digital Signature)的核心。
回到一開始的 對稱 vs. 非對稱加密。它們都是一種分類,而不是特定指某一種密碼學演算法(Algorithm),下面大概列一下常見的幾種,有興趣可以當作關鍵字搜尋:
對稱加密:AES
、DES
、Twofish
非對稱加密:RSA
、Elliptic Curve
數位簽章(Digital Signature)
雖然我們可以透過非對稱加密證明自己是送出訊息的一方,這麼做確有一個非常大的缺點,我們必須加密整個訊息。如果只有一句話到還好,但如果你今天要送出的是一個 Windows 的安裝檔呢?加/解密這個東西可是會需要很多時間的。
幸好,我們的工具箱裡面還有一個神奇的東西 —— Hash,又稱雜湊函式。
不管你輸入的是多長的訊息,它都可以產生一組 “獨一無二” 的指紋,是其他訊息無法產生的。
(注:其實 “獨一無二” 是一種比喻,還是有很低的機率會發生指紋相同的情況,叫做 hash collision,不過這裡不深入討論,只要知道現實生活中幾乎不可能發生就好了)
有了這個東西之後,我們就可以相對輕鬆的產生一個短短的雜湊值(指紋),而我們只要加密它就可以了。
Alice 收到之後,只要使用相同的 Hash 算法計算訊息的雜湊,然後與簽章進行比對就可以知道信息 是否有被其他人修改。
數位憑證(Digital certificate)
與前面提的到的 數位簽章(Digital Signature) 不同,多了 公開金鑰基礎建設(Public Key Infrastructure,PKI) 的設計。
在先前的例子裡面,我們並並沒有解釋 Alice 如何確認自己手上 Bob 的公鑰是真的 —— 因為沒有辦法去確認啊。
為了解決這個問題,我們需要一個公共的目錄: 把每個人的公鑰(Public Key)通通放上去,一個名子對應一個公鑰。
這個目錄的概念就是 公開金鑰基礎建設 —— 可信賴的第三者(Trusted third party,TTP) —— 不管是在哪裡拿到一把金鑰,只要他跟這個目錄上公告的一樣,我們就知道它是正確的。而負責維護這個目錄的角色,我們就稱之為 數位憑證認證機構(Certificate Authority,CA)。
一般來說,數位憑證通常會包含以下資訊:
- 主體(Subject):這個簽章的擁有者 aka 需要被驗證的那個人
- 主體(被驗者)的 公鑰(Public Key)
- 身分資訊(e.g. 這個人叫 Bob)
- 核發單位(Issuer)
- 數位簽章 ,也就是這份文件確實可信的證明)
- 單位資訊(e.g. 某某認證公司)
- 有效期限
- 演算法
但我們要怎麼知道一個憑證是有效的呢?這就要講回 數位憑證認證機構(Certificate Authority,CA) 啦~
現實生活中,我們當然也不會只有一個 CA,信任這種東西並沒有那麼非黑即白,今天去早餐店點一杯大冰奶,可以直接把錢跟菜單放櫃台,剩下的就不管;但如果今天買的是一台車,可就不能這麼隨便了。所以需要不同的 CA 來提供合適的服務(價格)。
所以就有了這樣的設計:由一個大家都相信,但很一板一眼的 CA 來認證幾個信得過的 CA,然後這個 CA 再去認證它相信的 CA,如此這般:
所以,當你拿到一個憑證,你必須一個一個往回找,直到找到這個可以信任的人(金鑰)為止。
X.509
OK 到了這裡,我們終於要回頭來講 HTTPS 的部份了!
我們都知道 HTTPS 使用 SSL/TLS 來進行封包的加密,而 SSL/TLS 使用的剛好就是 X.509 來進行身份驗證。(題外話:如果設定過 LDAP/X.500 的人可能會覺得 X.509 的憑證意外的有點熟悉)
如果把瀏覽網路的行為比喻成在大賣場購物的話,那 HTTP(s) 定義的大概就是結帳的過程了,而 X.509 則是那個商品的外包裝,保護並證明裡面的東西沒有被人動手腳。
換句話說,HTTPS 是一個 Protocol —— 定義訊息該如何被交換的規範;而 X.509 則是定義了拿到訊息之後,該怎麼確認內容沒有被動過手腳。
觀察已經設定好的網站伺服器(這邊以 Apache 舉例),我們可以看到 SSL 憑證的部份分成了兩個檔案:
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
SSLCACertificateFile /etc/ssl/certs/example.com.bundle.crt
</VirtualHost>
一個是 SSLCertificateFile
,這是認證機構(CA)簽過的檔案,裡面有我們的公鑰等資訊,
另一個就是 SSLCertificateKeyFile
,是我們自己的私鑰。
這兩個檔案該怎麼拿到,大致上會包含以下的流程:
- 先產生一對公、私鑰
- 準備一份憑證簽章請求(certificate signing request 通稱 CSR),按照格式把 Domain name 等資訊填入,並用私鑰簽章
- 把前面的 CSR 送到認證機構 CA
- 拿回來的就會是
example.com.crt
了(還有一個example.com.bundle.crt
)
小小解釋一下,這邊的 example.com.bundle.crt
紀錄的是從 Root CA 一路到你買的 CA 供應商,整串信任鏈的資訊!
使用素材
- patterns my wear eyes by SVG Silh / Public-Domain
參考資料
-
- 說真的,我從來都沒有聽過
公開金鑰
、私有金鑰
這種說法,我周遭的人都是直接講Public key
/Priavte key
- 說真的,我從來都沒有聽過
-
- a.k.a 數位憑證(Digital certificate)
-
- 中文版內容有點不太夠,建議搭配 英文版 一起服用
-
認識 PKI 架構下的數位憑證格式與憑證格式轉換的心得分享 | The Will Will Web
- 真不愧是保哥,內容跟參考資料真的都很豐富