在今日網路世界中,資訊安全議題越來越受到關注。 為了確保使用者在網站中進行數據交流的安全性,越來越多的網站開始使用 SSL(Secure Sockets Layer)憑證。 SSL 憑證使用加密技術來保護在網站之間傳輸的資料,包括使用者名稱、密碼、信用卡號碼等敏感資訊。這可防止駭客竊取這些資料,從而保護使用者的隱私和資訊安全。

SSL 憑證除了提升數據交換的安全性之外,還可以帶來其他重要的優勢,例如提升搜尋引擎排名以及增加使用者對您網站的信任度。 這表示您的網站將更容易在搜尋引擎中被找到,同時也能建立起使用者對於網站安全性的信心。 這不僅是一項資訊安全的投資,更是提升網站整體可信度和競爭力的重要手段。

本文紀錄了從購買 SSL 憑證到將憑證安裝到系統中的重要步驟流程,供大家參考。

SSL 運作流程

下圖是 SSL 運作的流程圖,簡單來說就是伺服器提供公開金鑰給客戶端進行資料加密,再進行資料傳輸,當伺服器收到資料後,再使用私密金鑰解密。 所以為了使用 SSL 加密傳輸,我們需要公開金鑰與私密金鑰這兩個檔案。 公開金鑰是從憑證供應商購買取得,私密金鑰是由我們自行產生。

* 公開金鑰及私密金鑰其實都能自己產生,只是自己產生的公開金鑰不是由可信任的數位憑證機構核發,所以瀏覽器還是會顯示不安全的網站連線。

選擇 SSL 憑證供應商

現在市場上有許多 SSL 憑證的供應商,如 GoDaddy遠振資訊TWCA, 還有不得不提的免費 SSL 憑證 Let's Encrypt,只是 Let's Encrypt 必需每 3 個月更新一次,雖然網路上有自動更新的方法,但這不是本文的重點。 此外,免費憑證也不提供任何賠償機制,而付費憑證通常包含賠償機制。 在購買憑證時,除了價格外,還有兩項重要的注意事項:

單一網域和無限次網域
選擇的方案,是否只能用於單一網域,或者可以用於任何的子網域。當然可以用於任何子網域的憑證,費用也會較高。
DV、OV 和 EV
網域名稱驗證 (DV)、組織驗證 (OV) 和延伸驗證 (EV) 這三類 SSL 憑證的主要差異在於其驗證程序的嚴謹性,而本身的資料加密技術是完全相同。
DV OV EV
驗證方式 網域所有權 申請者的組織身份 除了網域與組織驗證外,可能還會驗證對外電話、
申請速度
適用對象 部落格
個人網站
登入頁面
商業網站
電子商務
企業網站

建立 CSR 檔與私密金鑰

選擇完憑證供應商後,接下來需要建立私密金鑰及 CSR 檔 (有時也稱為憑證請求檔)。 打開終端機,輸入以下指令。

            
                openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr

                # 指令會輸入以下訊息,並詢問一些問題,請根據實際情況回答
                -----
                You are about to be asked to enter information that will be incorporated
                into your certificate request.
                What you are about to enter is what is called a Distinguished Name or a DN.
                There are quite a few fields but you can leave some blank
                For some fields there will be a default value,
                If you enter '.', the field will be left blank.
                -----
                Country Name (2 letter code) [AU]: (填寫國家名稱,例如:TW)
                State or Province Name (full name) [Some-State]: (填寫州或省名稱,例如:Taiwan)
                Locality Name (eg, city) []: (填寫城市名稱,例如:Tainan)
                Organization Name (eg, company) [Internet Widgits Pty Ltd]: (填寫組織或公司名稱)
                Organizational Unit Name (eg, section) []: (填寫組織單位名稱,例如:IT)
                Common Name (e.g. server FQDN or YOUR name) []: (填寫 SSL 安裝的網域名稱,很重要不能填錯。)
                Email Address []: (填寫信箱)

                Please enter the following 'extra' attributes
                to be sent with your certificate request
                A challenge password []: (留空,直接按 Enter)
                An optional company name []: (留空,直接按 Enter)
            
        

指令執行完成後,會產生 server.key 及 server.csr 兩個檔案。
server.key 是私密金鑰,屬於機敏資料,不應該在網路傳來傳去,單純放在網頁伺服器主機就好。
server.csr 是憑證請求檔,需要上傳給憑證供應商,後續憑證供應商會根據這份檔案核發公開金鑰。

上傳 CSR 檔並取得 SSL 憑證

現在您可以開始購買 SSL 憑證了。 在購買過程中,您將需要進行網域所有權的驗證,根據購買憑證的等級,可能還會有其他的驗證項目。 當購買完成後,就可以上傳 CSR 檔給憑證供應商,並等待 SSL 憑證核發,通常這個過程需要等待幾分鐘。 核發後,就可以下載 SSL 憑證了。根據不同的憑證供應商,您下載到的檔案格式可能會有所不同。

以 GoDaddy 為例您會拿到 (選其他):

  • 伺服器憑證:c12e3f456789101f.crt
  • 伺服器憑證:c12e3f456789101f.pem
  • 中繼憑證檔(包含根憑證):gd_bundle-g2-g1.crt

(兩個伺服器憑證內容一樣,副檔名不同而已)

以 TWCA 為例您會拿到:

  • 根憑證:root.cer
  • 伺服器憑證:server.cer
  • 中繼憑證1:uca_1.cer
  • 中繼憑證2:uca_2.cer

由於 TWCA 可能拿到兩個中繼憑證,我們需要將兩個憑證合併成一個檔案。

            
                cat uca_1.cer uca_2.cer > uca.cer
            
        

安裝 SSL 憑證

雖然不同的憑證供應商拿到的檔案不盡相同,但我們需要的就是伺服器憑證、中繼憑證及我們自己產生的私密金鑰。

以 Apache 為例,設定方式如下:

            
                SSLEngine on
                SSLCertificateFile      [伺服器憑證路徑]
                SSLCertificateKeyFile   [私密金鑰路徑]
                SSLCertificateChainFile [中繼憑證路徑]
            
        

以 Nginx 為例,設定方式如下:

            
                ssl_certificate         [伺服器憑證與中繼憑證合併檔路徑];
                ssl_certificate_key     [私密金鑰路徑];
            
        

Nginx 設定檔中的 ssl_certificate 參數值,需要將伺服器憑證與中繼憑證合併。

            
                cat c12e3f456789101f.crt gd_bundle-g2-g1.crt > server.crt
            
        

驗證 SSL 憑證

安裝完成後,可以直接開啟 Chrome 瀏覽器並打開您的網站,看看網址前面是否變成鎖頭了。 此外,以下網址還可以針對您的 SSL 安全性進行評分:

額外資訊

Diffie-Hellman 密鑰交換

大致上就是用來增加安全性的功能,尤其是在三向交握階段,但我還沒仔細研究運作原理,也沒有實作測試過。

以下是 Nginx 的設定流程,內容主要參考網路資訊,資訊不一定正確,建議謹慎參考。如果有有人測試成功或者哪邊有錯誤,也可以留言分享一下。

  1. 使用 OpenSSL 工具生成 DH 參數。
                            
                                openssl dhparam -out dhparam.pem 2048
                            
                        
  2. Nginx 設定文件中應用 DH 參數
                            
                                ssl_dhparam dhparam.pem;
                            
                        
  3. 重啟服務。
                            
                                sudo systemctl restart nginx
                            
                        
  4. 驗證是否生效。
                            
                                openssl s_client -connect your_domain:443 -cipher 'EDH'
                                # 或
                                openssl s_client -connect your_domain:443 -cipher 'ECDH'
                            
                        
    如果沒有發生錯誤的話,應該輸出類似以下的訊息:
                            
                                SSL handshake has read 3078 bytes and written 462 bytes
                                ...
                                Cipher is EDH-RSA-DES-CBC3-SHA
                                ...
                            
                        

    如果 Cipher 有看到 EDH 或 ECDH 的文字,表示設定正確。

啟動 OCSP

線上憑證狀態協定 (Online Certificate Status Protocol, OCSP) 是一種即時檢查憑證有效性的協定。 在 OCSP 推出之前,憑證的撤銷狀態主要通過憑證撤銷列表 (Certificate Revocation List, CRL) 進行檢查,該列表是一個包含大量資料的檔案,隨著時間推移,這個檔案會不斷膨脹,這就使得 Client 端在建立安全連線之前,需要下載並處理大量數據。 且由於更新週期時間差的問題,可能導致新撤銷的憑證狀態無法即時反映給 Client 端。 而 OCSP 主要就是為了解決這些問題。

不過 OCSP 早期因為效能及安全問題,是有一些批評的聲音,使用前可以多了解一下。

以在 Nginx 使用 GoDaddy 憑證為例:

  1. 請到 GoDaddy 網站下載 gd_bundle-g2-g1.crt 檔。
  2. 使用指令產生 stapling_ocsp 檔。
                            
                                # gd_bundle-g2-g1.crt 從步驟一下載
                                # server.crt 合併後的伺服器憑證
                                openssl ocsp -issuer gd_bundle-g2-g1.crt -cert server.crt -no_nonce -text -url https://ocsp.godaddy.com -text -respout stapling_ocsp
                            
                        
  3. Nginx 設定文件中啟動 OCSP
                            
                                ssl_stapling            on;
                                ssl_stapling_verify     on;
                                ssl_stapling_file       stapling_ocsp;
                                resolver_timeout        2s;
                                resolver                8.8.8.8 8.8.4.4 valid=60s;
    
                                ssl_trusted_certificate gd_bundle-g2-g1.crt;
                            
                        
  4. 重啟服務。
                            
                                sudo systemctl restart nginx
                            
                        
  5. 使用 SSL Server Test 工具確認 OCSP 是否正確啟動

證書密鑰匹配

如果這兩個指令的輸出值相同,即表示密鑰與憑證是匹配的。

                
                    openssl rsa -noout -modulus -in [密鑰路徑] | openssl md5
                    openssl x509 -noout -modulus -in [憑證路徑] | openssl md5