玩轉 SSL 證書

Introduction

Openssl 是一個很牛逼的工具,基本能搞定 PKI & HTTPS 證書相關的事情。這篇博文歸類了一堆常用的命令,全部都是關於 key & csr & crt。

本文分成兩部分,第一部分對 SSL/TLS 證書最核心的幾個名詞概念,第二部分則是一系列 openssl 常用命令。

轉載請註明出處: http://kyang.cc/


Key, CSR, CRT, CA 都是什麼?

什麼是 KEY、CRT ?

KEY 是指密鑰,通過一定長度的隨機數,經過指定的加密算法處理,得到後的一個文本密鑰文件。文件中既包含了 公鑰 Publib Key & Private key 兩個部分。

密鑰文件包含 PRIVATE KEY 字符,格式如下 (例子中採用 RSA 算法加密):

-----BEGIN RSA PRIVATE KEY-----
...............
-----END RSA PRIVATE KEY-----

CRT 是指證書,其與 KEY 是一對的。KEY 密鑰文件需要嚴格保密,而 CRT 證書文件卻是公開的。以 PC 瀏覽器上網爲例,瀏覽器通過向服務器 (如 https://github.com) 索取其 server.crt 證書,然後與瀏覽器內置的受信的 ca.crt 證書進行驗證。如果校驗成功,則瀏覽器會提示網站通過 https 連接是安全的。

證書文件包含 CERTIFICATE 字符,格式如下:

-----BEGIN CERTIFICATE-----
...............
-----END CERTIFICATE-----

什麼是 CSR ?

如果你想要一個 CA (Certificate Authority) 認證機構爲你頒發CRT 證書的話,那你需要先提供一個 CSR 請求文件。這個 CSR 請求文件中,會包含 Public Key 公鑰,以及一些申請者信息 (DN Distingusied Name)。

DN 信息中最最重要的部分,就是 Common Name (CN),這個成員需要與後續安放 CRT 證書的服務器,其主機域名 Fully Qualified Domain Name (FQDN) 完全一致才行。
請求文件包含 CERTIFICATE REQUEST 字符,格式如下

-----BEGIN CERTIFICATE REQUEST-----
...............
-----END CERTIFICATE REQUEST-----

什麼是 CA ?

CA 全稱爲 Certificate Authotiry,證書授權中心,又被成爲根證書。它類似於工商管理局,給公司企業頒發營業執照的。它主要有兩大主要特性:

  • CA 本身是受國際認可,受信任的
  • CA 需要給它受信任的對象頒發證書

證書長啥樣?其實你的電腦中有一堆 CA 證書。你可以看一看:

  • Chrome 瀏覽器:設置 -> 高級 -> 管理證書 -> 授權中心
  • Ubuntu: /etc/ssl/certs

CA 的證書 ca.crt 與 SSL Server 的證書 Server.crt 是什麼關係呢?

  1. SSL Server 自己生成一個 密鑰 KEY,內置包含 Private Key/Public Key, 私鑰加密,公鑰解密;
  2. Server 利用 密鑰 生成一個請求文件 server.csr,請求文件中包含有 Server 的一些信息,如域名/申請者/公鑰等;
  3. Server 將請求文件 server.csr 遞交給 CA,然後 CA 對其驗明正身後,將用 ca.key 和 server.csr 加密生成 server.crt 證書;
  4. 由於 ca.key 和 ca.crt 是一對,於是以後客戶端通過使用 ca.crt 就可以解密認證 server.crt 證書了。

在實際應用中:如果 SSL Client 想要校驗 SSL server。那麼 SSL server 必須要將他的證書 server.crt 傳給 client。然後 client 用 ca.crt 去校驗 server.crt 的合法性。如果是一個釣魚網站,那麼 CA 是不會給他頒發合法 server.crt 證書的,這樣 client 用 ca.crt 去校驗,就會失敗。比如瀏覽器作爲一個 client,你想訪問合法的淘寶網站(https://www.taobao.com,結果不慎訪問到 https://wwww.jiataobao.com ,那麼瀏覽器將會檢驗到這個假淘寶釣魚網站的非法性,提醒用戶不要繼續訪問!這樣就可以保證了client的所有https訪問都是安全的。

什麼是 SSL/TLS 單向認證,雙向認證 ?

單向認證,指的是隻有一個對象校驗對端的證書合法性。通常都是 client 來校驗服務器的合法性。那麼 client 需要一個 ca.crt,服務器需要 server.crt,server.key;

雙向認證,指的是相互校驗,服務器需要校驗每個 client,client 也需要校驗服務器。server 需要 server.key、server.crt、ca.crt;client 需要 client.key、client.crt、ca.crt;


Openssl 常用命令

生成 CSRs 請求文件

生成 CSR 請求文件的時候,需要填寫 DN Distingusied Name 信息。openssl 默認是通過 shell 交互讓用戶輸入,如下:

Country Name (2 letter code) [AU]: US

State or Province Name (full name) [Some-State]: New York

Locality Name (eg, city) []: Brooklyn

Organization Name (eg, company) [Internet Widgits Pty Ltd]: Example Brooklyn Company

Organizational Unit Name (eg, section) []:Technology Division

Common Name (e.g. server FQDN or YOUR name) []: examplebrooklyn.com

Email Address []:

如果你不想通過交互的方式,來填寫這些額外的信息。那則可以使用 -subj 選項,如下:

-subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=examplebrooklyn.com"

接下來的部分將會教大家如何生成與查看 CSR 文件。

產生一個新的 Private Key 和 CSR

如果你想使用 HTTPS (HTTP over TLS) 來加密你自己的 Apache HTTP or Nginx web server,並且你想通過 CA 來幫你解決 SSL 認證的問題。那採用以下命令,創建一個的密鑰 (domain.key) 和一個對應的 CSR 請求文件 (domain.csr):

openssl req \
        -newkey rsa:2048 -nodes -keyout domain.key \
        -out domain.csr

其中 -newkey rsa:2048 參數指定了密鑰應該通過 RSA 算法產生,長度爲 2048 bit。而 -nodes 選項指出產生的密鑰不需要額外通過 password 進一步加密。-new 選項在這裏是默認選項,既表明需要產生一個 CSR 請問文件。


通過已有的 Private Key 來產生 CSR

當你已經有了一個 Private Key,而且你想通過這個 Key 來向 CA 請求證書的話。那採用以下命令,通過已有的密鑰 (domain.key) 來產生 CSR 文件 (domain.csr):

openssl req \
        -key domain.key \
        -new -out domain.csr

填寫完 Distingusied Name 信息後,將會得到 CSR 請求文件。其中 -key 選項是爲了指明需要使用的 Existing Private Key (domain.key) ,而 -new 選項是爲了表明需要產生一個 CSR 請求文件。

如果產生 CSR 請求文件,所需的 Distingusied Name 的信息 以及 Private Key 密鑰都不變的情況下,那最後得到的 CSR 文件內容也不會變化。不論產生多少次,或者在不同操作系統上,最後得到的 CSR 內容也完全一致。


通過已有的 CRT 和 Private Key 來產生 CSR

當你想要找 CA 更新已有的 CRT 證書的時候,當時又找不到當初的 CSR 請求文件,那你就可以採用以下命令,從 CRT 證書中提取出所需要的 Distingusied Name 信息,與 Private Key 合成出 CSR 文件。

以下命令通過已有的 Private Key (domain.key) 和 CRT 證書 (domain.crt),來生成所需的 CSR 請求文件 (domain.csr)

openssl x509 \
        -in domain.crt \
        -signkey domain.key \
        -x509toreq -out domain.csr

其中 -x509toreq 選項既表明,想通過一個 X509 的 CRT 證書來生成一個 CSR 請求文件。


生成 CRTs 證書文件

如果你想要使用 SSL 來保證安全的連接,但是又不想去找 public CA 機構購買證書的話,那你就可以自己來生成 Self-signed Root CA 證書。

Self-signed 的證書也可以用來加密連接,只不過你的用戶在訪問你的網站的時候,將會提示出警告,說你的網站是不被信任的。因此當你開發的服務,並不需要提供給其他用戶使用的時候 (e.g. non-production or non-public servers),你纔可以使用 Self-signed 形式的證書。

生成 Self-Signed 的證書

以下命令將會生成一個 2048-bits 的 Private Key (self-ca.key) 和 Self-Signed 的 CRT 證書 (self-ca.crt):

openssl req \
        -newkey rsa:2048 -nodes -keyout self-ca.key \
        -x509 -days 365 -out self-ca.crt

其中-x509 選項是爲了告訴 req,生成一個 self-signed 的 X509 證書。而 -days 365 表明生成的證書有效時間爲 365 天。這條命令執行過程中,會產生一個臨時的 CSR 文件,但執行結束後就被刪除了。


通過已有的密鑰 Private Key 來產生 Self-Signed 證書

以下命令是通過已有的 Private Key (self-ca.key),來生成一個 Self-Signed 的 CRT 證書 (self-ca.crt):

openssl req \
        -key self-ca.key
        -new \
        -x509 -days 365 -out self-ca.key


通過已有的密鑰 Private Key & 請求文件 CSR 來產生 Self-Signed 證書

以下命令是通過已有的 Private Key (self-ca.key) 以及請求文件 (self-ca.csr),來生成一個 Self-Signed 的 CRT 證書 (self-ca.crt):

openssl x509 \
       -signkey self-ca.key \
       -in self-ca.csr \
       -req -days 365 -out self-ca.crt


通過已有的請求文件 CSR,通過 Self-Signed CA 來簽發 CRT 證書

以下命令是通過已有的 Self-Signed CA 的證書 (self-ca.crt) 和密鑰 (self-ca.key),和請求文件 CSR (domain.csr) 來簽發生成 CRT 證書 (domain.crt):

openssl x509 \
        -req \
        -CAcreateserial -days 365 \
        -CA self-ca.crt -CAkey self-ca.key \
        -in nginx.csr -out nginx.crt


校驗證書

Openssl 默認生成的證書相關的文件都是 PEM 格式編碼的,這部分通過 openssl 命令來解析這些文件。

查看請求文件 CSR

openssl req -text -noout -verify -in domain.csr

查看證書文件 CRT

openssl x509 -text -noout -in domain.crt

校驗證書文件 CRT 合法性

以下命令來校驗 domain.crt 證書,是否是由 ca.crt 證書籤發出來的:

openssl verify -verbose -CAFile ca.crt domain.crt

校驗 Private Key & CSR & CRT 三者是否是匹配

以下命令是分別提取出 Private Key (domain.key) & CSR (domain.csr) & CRT (domain.crt) 三者中包含的 Public Key,然後通過 md5 運算檢查是否一致:

openssl rsa -noout -modulus -in domain.key | openssl md5
openssl req -noout -modulus -in domain.csr | openssl md5
openssl x509 -noout -modulus -in domain.crt | openssl md5


CRT 格式轉換

上面通過 X509 證書生成的證書,都是 ASCII PEM 格式進行編碼的。然而證書也可以轉換成其他格式,有些格式能夠將 Private Key & CSR & CRT 三者全部打包在同一個文件中。

PEM 格式 vs DER 格式

The DER format is typically used with Java.

  • PEM 格式轉成 DER 格式
openssl x509 \
        -in domain.crt \
        -outform der -out domain.der
  • DER 格式轉成 PEM 格式
openssl x509 \
        -inform der -in domain.der \
        -out domain.crt

PEM 格式 vs PKCS7 格式

PKCS7 files, also known as P7B, are typically used in Java Keystores and Microsoft IIS (Windows). They are ASCII files which can contain certificates and CA certificates.

  • PEM 格式轉成 PKCS7 格式
openssl crl2pkcs7 -nocrl \
        -certfile domain.crt \
        -certfile ca-chain.crt \
        -out domain.p7b
  • PKCS7 格式轉成 PEM 格式
openssl pkcs7 \
        -in domain.p7b \
        -print_certs -out domain.crt

如果你的 PKCS7 文件中包含了多個證書文件 (e.g. domain.crt & ca.crt) ,那上面命令生成的 PEM 文件中將同時包含所有被打包的證書。

PEM 格式 vs PKCS12 格式

PKCS12 files, also known as PFX files, are typically used for importing and exporting certificate chains in Micrsoft IIS (Windows).

  • PEM 格式轉成 PKCS12 格式
openssl pkcs12 \
        -inkey domain.key \
        -in domain.crt \
        -export -out domain.pfx
  • PKCS12 格式轉成 PEM 格式
openssl pkcs12 \
        -in domain.pfx \
        -nodes -out domain.combined.crt

示例案例

我自己搭建的 Nginx Web Server 想要提供 HTTPS 連接方式,但是覺得不想花錢去找知名 CA 證書中心 (e.g. AWS Certificate Manager) 購買證書。於是我想通過 Self-Signed 的方式來解決我的需求:

  1. 先生成 Self-Signed CA 證書:
openssl req \
        -newkey rsa:2048 -nodes -keyout self-ca.key \
        -x509 -days 365 -out self-ca.crt
  1. 生成 Nginx Web Server 需要的 Private Key & CSR :
openssl req \
        -newkey rsa:2048 -nodes -keyout nginx.key \
        -out nginx.csr
  1. 利用 Self-Signed CA 證書,來簽發業務所需要的 CRT 證書:
openssl x509 \
        -req -in nginx.csr \
        -out nginx.crt \
        -CAcreateserial -days 365 \
        -CA self-ca.crt -CAkey self-ca.key

經過了上面 3 個步奏後,你就得到了 self-ca.crt & self-ca.key ,以及由它籤發出來的 nginx.crt & nginx.key

如何使用上面 4 個文件:首先將 nginx.crt & nginx.key 部署在 Nginx Web Server 上,然後將 self-ca.crt 發佈給客戶端即可。客戶端就可以通過 self-ca.crt 與業務服務器建立 SSL/TLS 安全連接。

Reference

SSL-TLS 雙向認證(一) – SSL-TLS工作原理

OpenSSL Essentials: Working with SSL Certificates, Private Keys and CSRs

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章