小明: OK,我已經申請好HTTPS的憑證了,只要把ca_bundle.crt
, certificate.crt
, private.key
放入Server我們網站就有HTTPS囉。
小美: 太好了,是說這三個檔案到底是什麼呢?
小明: ㄜ ...我記得HTTPS是用非對稱式加密,會有把公鑰,有把私鑰,然後瀏覽器端透過公鑰加密,然後傳到Server上透過私鑰來解密,對吧?
小美: 可是這三個檔案好像不是非對稱式加密那麼簡單,certificate.crt
叫做憑證,ca_bundle.crt
叫做中間憑證,我壓根沒看到公鑰的檔案啊。
小明: ...讓我Google一下...
不知道大家是否有遇到以上狀況,我在以前透過憑證來替Server安裝HTTPS時,其實我只是將憑證安裝完畢,但是並不知道實作內容到底是什麼樣子,這篇文章就來介紹一下HTTPS的概念。
我們可以先有個簡單的觀念就是:
資料可以透過公鑰加密,但無法透過公鑰解密,只能透過私鑰解密。
資料可以透過私鑰加密,但無法透過私鑰解密,只能透過公鑰解密。
因為只能靠不同把鑰匙解密,所以我們稱為「非對稱」
因為如果可以靠「同一把」鑰匙解密,雖然我們理想上可以透過下圖加密資料:
但實際上很容易因為鑰匙被攔截,而導致資料外洩:
如果加密資料不能用「同一把」鑰匙解密,就可以避免這個問題了,所以套到攔截的情境會變成下圖:
這是個更棘手的狀況,因為攻擊者可以趁機替換小明拿到的公鑰,如下圖:
小明的資料還是照樣被偷走了,那要怎麼辦呢?
我們需要一個公正的第三方證明,此公鑰是此Server的
我們可以先有個簡單的概念:
憑證 = 公鑰 + 此公鑰是屬於哪個Server的資訊 + 數位簽章
我們的公鑰可以透過一個有公信力的第三方來證明是此Server的公鑰,而不是來路不明的攻擊者,此方法是透過數位簽章。
數位簽章與加密相反,他是透過「私鑰加密,公鑰解密」,他讓我們的公鑰是有第三方簽名的,如圖:
這個簽名擁有這個公鑰的屬於哪個Server的資訊,而簽章要解密就需要公鑰,所以我們的瀏覽器都有這些「第三方公鑰庫」,瀏覽器配合第三方公鑰庫可以這樣驗證憑證:
所以套回攻擊者的情境就會變成下圖:
小明的瀏覽器就會跳出下圖,就是說明此憑證不是第三方公鑰庫擁有的:
在攻擊者無法進行任何攻擊手段時,正常安全的Client與Server溝通流程如下:
有趣的是,其實不止瀏覽器,我們的任何程式,都有類似的第三方公鑰庫去驗證HTTPS的簽章是否符合正常,比如說Node.js在詢問到沒看過的HTTPS簽章時就會出現下圖:
接下來,介紹一下HTTPS實際怎麼運作,
其實Client並不會每次都用非對稱加密與Server溝通,只有在「第一次」,而已,可以參考此篇文章
裡面的圖講解的很清楚,在此貼上
圖的意思整體是說:
透過「非對稱式加密」,讓瀏覽器可以「安全的」傳送一個鑰匙給Server,我們稱為Session KEY,之後瀏覽器與Server溝通就透過此Session KEY來做「對稱式加密」
為什麼要這樣呢?因為非對稱式加密的數學演算較久,而對稱式加密較快,我們可以透過非對稱式加密來達到「安全傳送鑰匙」的效果,再透過此鑰匙用一般的對稱加密,就可以又快又安全了~
雖然我們整個流程貌似完全安全了,但還有最後一個破口,就是「第三方」,如果第三方的私鑰被偷竊,那所有透過此第三方簽出去的憑證都會有安全上的危險,因為偷竊者可以使用此私鑰來製作一模一樣的簽章。
那要怎麼分散風險呢?最簡單的方法就是:
不要很常用這個我們稱為「根憑證」的原始私鑰,把他一直藏著,就不會被偷啦!
是不是讓人覺得這方法很沒技術性?但仔細想想,這的確就是最根本的解決辦法xdd,我們可以看看知名的第三方組織Let's Encrypt的根憑證保護方法,是將根憑證「離線儲存在安全地點」,
但我們還是需要簽證呀,總不能每次簽證都要請人員跑道安全地點拿私鑰來簽證吧,為此第三方會再做出多組公私鑰,並用根憑證的私鑰簽這些公鑰,這些簽完的公鑰就將我們稱為「中間憑證」,根憑證的私鑰簽完就可以先離線儲存在安全地點了,我們後來的簽證都靠中間憑證的私鑰來做。
如果我們Server去請第三方幫忙簽章,第三方都會用此中間憑證的私鑰來簽章,這樣一來,如果中間憑證的私鑰被偷,也只有被這組簽發的憑證會報銷。
這邊提出我當初學習常常有的誤解:
謝謝你的觀看,也歡迎指正交流~感謝!
愚者剛入門開始學習SSL安全機制,想釐清一些關念,如有愚見敬請見諒:
憑證=由公鑰和公鑰資訊+數位簽章
因為我想要實作,所以急著看了一些文章如何產生憑證:
http://ijecorp.blogspot.com/2014/03/openssl.html
https://www.arubacloud.com/tutorial/how-to-create-a-self-signed-ssl-certificate-on-ubuntu-18-04.aspx
上面兩個文章好像都用私鑰建立憑證需求,最後得到憑證.
中間好像還少了建立公鑰的部份?
想問的是,公鑰是在建立憑證需求時被產生的嗎?還是在建立私鑰的時候呢?
公鑰是在建立憑證需求時被產生的嗎?還是在建立私鑰的時候呢?
ans: 私鑰的時候。公鑰是透過私鑰產生,此文都沒有提到公鑰,是因為此文情境用不到。
正如上面所說公鑰是透過私鑰產生,所以私鑰也可以產生一個憑證簽章請求(CSR),並請有公信力單未簽核,就可以產出有簽證的公鑰了(即是憑證)。
如果不需要公信力,簽核單位也可以是自己的私鑰,即是self-signed(自簽)
您好,感謝你的回覆,但如果要傳(憑證需求+私鑰)給憑證機構幫忙生出憑證,那不會很不安全嗎?
照理說應該是傳(憑證需求+"公"鑰)給憑證機構,這樣比較安全.