網絡知識學習:https服務的原理和實現

https詳解

目前大部分大型網站已經全部切換到了https服務,所以很有必要了解整個https的原理,https是如何保證信息安全的。這裏希望大家對以下部分名詞有一定的瞭解:

  • 數字證書
    是互聯網通信中的身份標識(主要是用戶身份信息和公鑰),一般由CA中心頒發,既CA認證中心,或第三方權威機構。數字證書上通常包括:CA的簽名,證書所有人的公鑰,CA中心的簽名算法,指紋以及指紋算法,證書的唯一編號,版本,有效期等。
  • 數字簽名、簽名算法
    對信息的摘要【通過hash算法/摘要算法/指紋算法計算的信息摘要/hash值】使用簽名算法進行加密,得到的密文就叫做數字簽名
  • 指紋、指紋算法/摘要算法【hash值計算】
    對消息使用hash算法/摘要算法進行單向處理,獲取一個固定長度的信息的摘要/hash值
  • 非對稱加密
    可以使用公鑰、私鑰分解進行對應的加密、解密的算法,即加解密使用的是不同的一堆祕鑰。
  • 對稱加密
    使用相同祕鑰進行加解密的算法
  • 公鑰、私鑰
    非對稱加解密的一對祕鑰。

https服務部署過程和原理

瞭解https的原理,最好的方法就是走一遍流程,理論上的流程和原理通過以下幾點來解釋:

  1. 證書申請
  2. 證書信任
  3. 密文通信

證書的獲取

https的關鍵之一就是ssl證書,爲了保證證書的安全有效性,在各類委員會/廠商之間合作,通過類似圓桌會議來形成若干權威的認證機構【頂級認證機構可以有若干附屬的二級、三級...認證機構】,想要得到受信任的證書,就需要向CA機構提交證書籤名請求 (CSR, Certificate Signing Request)。過程如下:

  1. 證書申請者【一般是公司、個人開發者等】需要使用加密算法【大部分是RSA算法】來生成私鑰,其中私鑰保存在服務器上,不提供給任何人。
  2. 使用私鑰生成證書籤名請求 (CSR, Certificate Signing Request)【CSR中附帶有公鑰】,需要提供一些申請者相關的信息【域名、擁有者等信息】,發送給CA機構請求他們的簽名,經過他們簽名才能成爲被信任的證書。
  3. CA機構對申請者進行驗證【這裏不同類型收費不同,驗證方式也會不同】,驗證通過後,將會在證書中添加部分信息【證書頒發機構、有效期、指紋/hash算法、簽名算法】,形成新的證書。【CA機構也是使用其自身的私鑰來簽名其他證書的】
  4. 對新的證書進行簽名,步驟如下:

    • 對新證書按照指紋/hash算法進行hash值計算
    • 使用CA機構的私鑰對計算出來的hash值按照簽名算法進行加密,得出的密文就是數字簽名;
    • 將數字簽名放在證書的最後面【簽名完成】,得到完整的證書,並返回給申請者;
    • 申請者獲取簽名證書,保證自己的HTTPS服務被信任。

圖片描述
所以最後的證書基本包括但不限於的內容如下:

  • 證書的有效期
  • 公鑰
  • 證書所有者(Subject)
  • 簽名所使用的算法
  • 指紋以及指紋算法【hash算法】
  • Version Number,版本號。
  • Serial Number,序列號。
  • 頒發機構
  • 數字簽名

客戶端識別證書

在申請到受信任的證書後,客戶端是怎麼知道這些證書是值得信任的呢,不同瀏覽器和系統的具體實現不太一樣,但是基本的方式差不多,都是在系統或者瀏覽器中事先準備好權威的CA機構的相關信息[公鑰、常使用的各類hash、簽名、加密算法等]。具體過程如下:

  1. 瀏覽器訪問某https服務,帶上瀏覽器自身支持的一系列Cipher Suite(密鑰算法套件,後文簡稱Cipher)[C1,C2,C3, …]發給服務器【算法套件包括非對稱算法、對稱算法、hash算法】;
  2. 服務器接收到瀏覽器的所有Cipher後,與自己支持的套件作對比,如果找到雙方都支持的Cipher【雙方套件中都能支持的最優先算法】,則告知瀏覽器,並返回自己的證書;
  3. 瀏覽器確認和服務端後續的密文通信的加密算法,同時對證書進行認證;
  4. 使用證書中的認證機構【可能是二級、三級機構】的公鑰【系統、瀏覽器事先準備好的】按照證書中的簽名算法進行解密【認證機構使用私鑰加密的密文只能通過該認證機構的公鑰進行解密】,解密獲取hash值;
  5. 使用證書中的hash/摘要算法對證書信息【證書籤名除外的信息[服務器公鑰、有效期等]】hash值計算,和4中解密的hash值進行對比,如果相等,表示證書值得信任;【通過數字簽名來保證證書內容沒有被篡改】。

圖片描述

https的加密通信過程

在上文的流程之後【證書信任,客戶端和服務端握手中需要的非對稱算法握手信息驗證的hash算法正文傳輸的對稱加密】,就是具體的通信過程:

  1. 客戶端信任了服務端的證書,並和服務端確認了雙方的加密算法【握手中需要的非對稱算法握手信息驗證的hash算法正文傳輸的對稱加密】;
  2. 客戶端生成隨機數,通過證書中的公鑰按照約定的非對稱加密算法進行加密,得到加密的隨機數祕鑰,同時將之前所有的通信信息【祕鑰算法套件、證書等所有的通信內容】按照約定的hash/摘要算法獲取hash值,並使用隨機數和協商好的對稱加密算法進行簽名加密,將隨機數祕鑰和加密簽名發送到服務端。
  3. 服務端收到隨機數祕鑰和加密簽名,先使用私鑰將隨機數按照約定的非對稱解密算法進行解密,獲取隨機數,同時使用隨機數按照約定的對稱解密算法進行解密,獲取待驗證的hash值,將之前的通信消息體【祕鑰算法套件、證書等所有的通信內容】按照約定的hash/摘要算法獲取hash值,與剛纔解密獲取的待驗證的hash值對比,驗證加密成功與否。
  4. 成功以後,服務器再次將之前所有的通信信息【祕鑰算法套件、證書等所有的通信內容】按照約定的hash/摘要算法獲取hash值,並使用隨機數和協商好的對稱加密算法進行簽名加密,將隨機數祕鑰發送到客戶端,
  5. 客戶端使用隨機數按照約定的對稱解密算法進行解密,獲取待驗證的hash值,將之前的通信消息體【祕鑰算法套件、證書等所有的通信內容】按照約定的hash/摘要算法獲取hash值,與剛纔解密獲取的待驗證的hash值對比,驗證加密成功與否,
  6. 成功的話整個鏈接過程完成,之後將使用隨機數和約定的對稱加密算法進行密文通信,【如果上面的任何步驟出現問題,都將會結束整個握手過程,導致建立安全連接失敗】。

圖片描述

整個過程其實還有很多細節;ssl握手報文

綜合解惑

這裏的整個過程分的很細,不過還是很清晰的把整個https的原理和過程闡述了;下面解釋一下其中一些疑惑點:

  1. CA機構認證的作用?
    可以作爲全球有限的權威認證,經過其簽名的證書都可以視爲可信任的,所以他們的私鑰必須要保證不被泄露,如果泄露的話需要及時的進行吊銷,
  2. 簽名爲什麼需要加密計算的hash值,hash值已經是單向不可逆的運算了?
    因爲雖然hash值是單向的,但是計算hash的算法和內容都是公開的,如果不進行加密,那麼由於其他人可以修改證書內容,根據hash算法重新計算hash,這樣就會出現安全漏洞,所以使用加密的密文才是安全的。
  3. 爲什麼要有隨機數,爲什麼在客戶端生成?
    隨機數是作爲後續整個密文加解密的關鍵祕鑰,只有獲取這個隨機數的人纔可以看到通信的內容,保證通信的安全;通過客戶端產生是因爲會話的發起者是用戶端,爲了保證用戶端的唯一,以及保證服務端和客服端的會話內容不被篡改,如果是服務端來生成的話,第三方可以通過公鑰來解密服務端加密的隨機數,存在不安全因素。
  4. 證書驗證完成後,爲什麼客戶端需要和服務端互相發送一次簽名信息?
    證書驗證完成以後,需要傳遞一個隨機數,使用公鑰、私鑰進行非對稱加解密,後面在發生內容消息的前面是爲了驗證通過隨機數進行對稱加解密,保證雙方獲取的數據正確性。

openssl生成證書

在大部分開發調試過程中,我們需要本地調試https的頁面時候,我們需要在本地擁有證書,而openssl就是就是這樣一個集成工具;通過使用openssl來完成本地調試https的請求。

  1. openssl簡介
  2. 自簽名證書
  3. 本地私有CA證書

openssl的簡介

OpenSSL 是一個開源項目,其組成主要包括一下三個組件:

  1. openssl:多用途的命令行工具
  2. libcrypto:加密算法庫
  3. libssl:加密模塊應用庫,實現了ssl及tls

openssl可以實現:祕鑰證書管理、對稱加密和非對稱加密更多簡介官網openssl簡介

自簽名證書

爲了能夠把線上的https的請求,走向本地,需要我們本地也有https服務,那麼證書就是不可避免的,然而一般情況我們並不是使用線上的證書,因爲走本地需要本地啓用服務,如果證書使用線上的,那麼本地起服務的話就需要線上的私鑰等隱私信息,這很容易導致私鑰泄露,所以不安全,那麼我們就需要生成一個本地的證書;

前文講過了,一個證書是需要經過CA機構進行認證簽名的,那麼我們本地測試使用的證書然道也要去申請認證嗎?但是否定的,因爲這個這是隻是我們本地使用,所以只需要我們有證書,並且手動添加信任就行,那麼自簽名證書就很好的解決了這個問題。

自簽名證書跟多詳細介紹,自簽名證書的核心就是自己對自己的申請進行簽名【CA根證書就是這樣產生的】;使用自己的私鑰對自身生成的證書申請CSR進行簽名得出的證書。

通過自簽名證書我們獲得了https服務需要的證書,根據本地不同的環境,都需要對該證書進行一個信任,這樣我們本地起的https服務纔會被瀏覽器正確的識別。整個過程如下:

  1. 生成祕鑰

    openssl genrsa -des3 -out cwj.key 2048

    使用以上命令,來生成一個我們本地需要的私鑰,後面需要使用私鑰來生成證書申請CSR以及對證書申請CSR使用私鑰進行自簽名

  2. 生成證書申請CSR

    openssl req -new -key cwj.key -out cwj.csr

    需要填寫一系列信息,包括地點、單位、域名、email之類的,這裏會自動使生產與服務端私鑰匹配的公鑰,CSR中包含了公鑰;

  3. 使用私鑰完成自簽名,生成完整的證書

    openssl x509 -req -sha256 -days 3650 -in cwj.csr -signkey cwj.key -out cwj.crt

    使用前生產的祕鑰對證書申請CSR進行信任簽名,得到完整的證書;

這樣的確滿足了部分需求,只需要使用該證書和私鑰來啓動https服務,同時本地信任這個證書就大功告成了,其中優點如下:

  1. 本地自簽名,無須CA根證書;
  2. 過程簡單

不過也存在一些弊端:

  1. 該證書無法被吊銷,私鑰需要保存好,不過對於僅用於本地調試來說就無傷大雅;
  2. 多域名需要多個證書,需要根據域名生成多個證書,客服端需要分別信任這些證書。【不過openssl也可以生成多域名證書,一個證書可以供多個域名使用,一般使用openssl.cnf配置文件來生成】

所以還存在其他的方法:爲了模擬完整的真是的https服務,我們可以在本地生成一個類似CA根證書,通過CA的私鑰來對其他的所有的本地證書進行簽名,只有信任了本地的CA根證書,那麼他簽名的證書都會被信任,這樣就是下面文提到的進化方法本地私有CA根證書

本地私有CA根證書僞CA根證書

這個方法的整體流程就是本地生成一個CA證書,就類似CA機構的存在,【暫且稱爲僞CA根證書】通過僞CA根證書的私鑰來對其他的所有的本地證書進行簽名,我們本地信任了這個僞CA根證書,那麼通過僞CA根證書簽名的證書都會被信任。避免了多個域名需要生成多個自簽名證書以及要進行分別信任的複雜行爲。

  1. 僞CA根證書生成並添加信任

    openssl genrsa -des3 -out ca.key 2048
    openssl req -new -key ca.key -out ca.csr
    openssl x509 -req -sha256 -days 3650 -in ca.csr -signkey ca.key -out ca.crt

    可以看到,其實ca根證書就是一個自簽名證書的例子;

  2. 本地單一域名證書祕鑰、申請CSR

    openssl genrsa -des3 -out cwj.key 2048
    openssl req -new -key cwj.key -out cwj.csr

    生成一個證書請求;

  3. 僞CA根證書的私鑰簽名其他的申請CSR

    openssl x509 -req -sha256 -days 3650 -in cwj.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out cwj.crt

更多內容openssl;這樣證書的問題就解決了,視情況來看使用者是採用哪種方案來生成證書。

信任證書需要一些操作,不同系統有不同的過程,MAC是在鑰匙串中信任,windows是需要導入證書;

nginx部署https實踐

本地啓動https服務的方式很多,這裏就說一說nginxnginx官網https模塊,主要用到的就是私鑰和證書;根據之前提到的使用不同方法生成的證書以及服務器私鑰【本地CA根證書也需要本地進行信任】。

server {
        listen       443 ssl;
        server_name  cwj.cc;

        ssl_certificate      /cwjhttps/cwj.crt;
        ssl_certificate_key  /cwjhttps/cwj.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   /cwjhttps;
            index  home.html index.htm test.html;
        }
    }

其實這樣的做法在chrome高版本還是會被認爲是不安全網站;後面的openssl的介紹會具體的進行說明,或者參見自簽名證書過程詳解解決chrome不信任自簽名證書摘要/hash算法不被認爲安全

發佈了73 篇原創文章 · 獲贊 23 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章