最近有一項作業是實作利用 TLS 通訊的網路程式,需要自行為 Server 跟 Client 產生金鑰跟憑證來做驗證。一直以來都只有用方便又快速的 Certbot 來幫忙上 SSL,剛好就趁這個時候來玩玩看自簽憑證吧!


Requirements

  • OpenSSL

what is OpenSSL

OpenSSL是一套加密工具,實作了 TLS 協定還有各種加密標準。在這篇文章中,我們將用他來產生金鑰跟憑證。


建立簡單的 CA (Certificate Authority)!

首先要先幫我們的 CA 產生一把私鑰,這裡的參數 -aes256 代表產生出來的私鑰會用 AES 加密,因此會要求輸入一組密碼作為 AES 的 key。之後簽署 Certificate signing request(CSR)的時候都需要輸入這組密碼來驗證。

openssl genrsa -aes256 -out root/ca.key 4096

再來要用這把私鑰產生一份自我簽署的憑證。

openssl req -new -x509 -days 365 -sha256 \
        -subj "/C=TW/ST=Taipei/O=FOO/OU=BAR/CN=xueyuan.dev/emailAddress=denon@xueyuan.dev" \
        -key root/ca.key \
        -out root/ca.crt

到這邊為止,我們的 CA 就算建立完了,接下來就可以用它去簽 CSR 和發憑證啦!


產生 Server/Client 的 key 和 CSR

這邊的步驟跟產生 CA 的 key 一樣,不過我們可以省略加密。

openssl genrsa -out server/server.key 4096

接著產生 CSR,

openssl req -new -sha256 -key server/server.key \
        -subj "/C=TW/ST=Taipei/O=FOO/OU=BAR/CN=xueyuan.dev/emailAddress=denon@xueyuan.dev" \
        -out server/server.csr

3. 發憑證!

Key 跟 CSR 產生完後就交給我們 CA 來簽署跟發證啦~

openssl x509 -req -CAcreateserial -days 30 -sha256 \
        -CA root/ca.crt -CAkey root/ca.key \
        -in server/server.csr \
        -out server/server.crt 

4. 檢視及驗證

檢視憑證內容

openssl x509 -noout -text -in client/client.crt

驗證剛剛產生的憑證是否由我們的 CA 所簽署的,

openssl verify -CAfile root/ca.crt client/client.crt

5. 結論

一般來說我們的憑證不是只有 Root CA 簽署,中間還會有許多 CA 參與,這些 CA 又叫做中繼 CA(Intermediate CA),這樣可以減少 Root CA 的簽名被暴露的風險。由這些 CA 簽發下來的憑證會形成一個憑證鍊(Certificate Chain),大概會長得像這樣:

-----BEGIN CERTIFICATE-----
# Base64–encoded certificate
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
# Base64–encoded certificate
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
# Base64–encoded certificate
-----END CERTIFICATE-----

每一層的憑證會去認證上一層的憑證。


參數說明

  • Standard Command:
    • genrsa: 用來產生 key 的,後面要接上 key 的長度。
      • -aes256: 用 aes 加密這把 key,也有其他加密標準可選,例如:des3
    • req: 用來建立和處理憑證請求,也可以建立自簽憑證。
      • -x509: 建立自簽憑證。
      • -days: 指頂這份憑證的有效天數,與 -x509 一起使用。
      • -subj: CSR 的 設定,省略的話後續的流程也會要你輸入。其中每個符號的意義分別是:
        • C: Country
        • ST: State
        • O: Organization
        • OU: OrganizationalUnit
        • CN: CommonName,通常為 Domain name
        • emailAddress: 就是 email
    • x509: 用來簽署、顯示或是編輯憑證
      • -req: 確保輸入的檔案是 CSR 而不是 CRT
      • -CAcreateserial: 建立一個檔案(.srl)來記錄簽了幾個憑證
      • -noout: 不輸出編碼版本
    • verify: 驗證憑證鍊

OpenSSL 主要分三種功能,除了這次用到的 Standard Commands 外,還有 Message Digest Commands 和 Cipher Commands


References