當我們需要在企業內部或者測試環境中使用證書時,往往需要創建自簽名證書。Linux系統中的Openssl工具可以用來生成自簽名證書,實現通信的加密,也可以基于自簽名的CA證書模擬實際CA信任鏈的工作過程。本文基于Openssl介紹自簽名證書的生成和應用實踐。
自簽名證書分為自簽名私有證書和自簽名CA證書兩種。自簽名私有證書無法被吊銷,自簽名CA證書可以被吊銷。能不能吊銷證書的區別在于如果私鑰不小心被惡意獲取,如果證書不能被吊銷那么黑客很有可能偽裝成受信任的客戶端與用戶進行通信。如果你的規劃需要創建多個客戶端證書,那么使用自建 CA 簽名證書的方法比較合適,只要給所有的客戶端都安裝了 CA 根證書,那么以該 CA 根證書簽名過的客戶端證書都是信任的,不需要重復的安裝客戶端證書。
請注意由于是自建 CA 證書,在使用這個臨時證書的時候,會在客戶端瀏覽器報一個錯誤,簽名證書授權未知或不可(signing certificate authority is unknown and not trusted.),但只要配置正確,繼續操作并不會影響正常通信。 自簽名證書的 Issuer 和 Subject 是一樣的。下面就分別闡述如何使用 OpenSSL 生成這兩種自簽名證書。
生成自簽名私有證書
- 生成證書私鑰(Key)
#生成私鑰
openssl genrsa -out /path/to/keyfile 2048
2. 如果需要備份或者轉移私鑰,需要先對私鑰進行加密
#私鑰加密,用于備份或者轉移私鑰
openssl rsa -in /path/to/keyfile -des3 -out /path/to/encrypted.key
3. 生成證書請求文件(Certificate Sign Request)
生成 CSR 的過程中,會提示輸入一些信息,包括:序列號、公鑰、用戶名稱、簽發者、CA簽名和其他一些附屬信息等。證書驗證過程就是依賴于這信息和公鑰對應的私鑰進行。其中一個提示是 Common Name (e.g. YOUR name),這個非常重要,這一項應填入 FQDN(Fully Qualified Domain Name)完全合格域名/全稱域名,如果您使用 SSL 加密保護網絡服務器和客戶端之間的數據流,舉例被保護的網站是 https://test.example.cn
,那么此處 Common Name 應輸入 test.example.cn
#生成證書請求文件(Certificate sign request)
openssl req -new -key /path/to/keyfile -out /path/to/csrfile
4. 使用上一步的證書簽名請求簽發證書(Certificate)
#自簽名,生成私有證書
openssl x509 -req -in /path/to/ssl.csr -signkey /path/to/ssl.key -out /path/to/ssl.crt
5. 查看證書信息
#查看證書信息
openssl x509 -in /path/to/certfile -noout -text
上面的1-4步也可以通過命令行合并為一步實現
openssl req -new -x509 -newkey rsa:2048 -keyout /path/to/server.key -out /path/to/server.crt
生成自簽名CA證書
創建自簽 CA 證書,主要分為兩個部分: 創建CA 根證書及簽發客戶端證書。
創建CA根證書
使用 OpenSSL 可以創建自己的 CA,給需要驗證的用戶或服務器頒發證書,這就需要創建一個 CA 根證書。默認情況ubuntu和CentOS上都已安裝好openssl。CentOS 6.x 上有關ssl證書的目錄結構。
/etc/pki/CA/
newcerts 存放CA簽署(頒發)過的數字證書(證書備份目錄)
private 用于存放CA的私鑰
crl 吊銷的證書
/etc/pki/tls/
cert.pem 軟鏈接到certs/ca-bundle.crt
certs/ 該服務器上的證書存放目錄,可以房子自己的證書和內置證書
ca-bundle.crt 內置信任的證書
private 證書密鑰存放目錄
openssl.cnf openssl的CA主配置文件
在創建 CA 根證書之前,需要做好如下準備工作:修改好 CA 的配置文件、序列號、索引等等。
touch index.txt serial
echo 01 >> serial
openssl的配置文件為openssl.cnf,一般存儲在/etc/pki/tls/目錄下。一定要注意配置文件中 [ policy_match ]標簽下設定的匹配規則。有可能因為證書使用的工具不一樣,導致即使設置了csr中看起來有相同的countryName,stateOrProvinceName等,但在最終生成證書時依然報錯。一般情況下,配置文件不需要改動。
- 生成根證書密鑰
# 生成CA根證書密鑰
cd /etc/pki/CA/
openssl genrsa -out ./private/ca.key 2048
2. 生成根證書請求
# 新建根證書請求
openssl req -new -in /path/to/ca.key -out ca.csr
3. 生成根證書
#自簽名,生成CA證書
openssl x509 -req -in /path/to/ca.csr -signkey /path/to/ca.key -extensions v3_ca -out /path/to/ca.crt
簽發證書
我們可以用CA根證書簽發證書,也可以創建中間CA,使用中間CA簽發證書。創建中間CA的好處是即使中間CA的私鑰泄露,造成的影響也是可控的,我們只需要使用root CA撤銷對應中間CA的證書即可。此外root CA的私鑰可以脫機妥善保存,只需要在撤銷和更新中間CA證書時才會使用。基于根證書創建中間CA與創建根證書過程類似。我們新建一個目錄用于保存中間證書信息。
#準備環境
mkdir /etc/pki/CA/intermediate
cd /etc/pki/CA/intermediate
mkdir certs crl newcerts private
chmod 700 private
touch index.txt
echo 1000 > serial
#生成密鑰
cd /etc/pki/CA
openssl genrsa -aes256 -out intermediate/private/ca.key 2048
#新建請求
openssl req -config intermediate_CA.cnf -sha256 -new -key intermediate/private/ca.key -out intermediate/certs/ca.csr
#簽發中間CA證書
openssl ca -config root_CA.cnf -extensions v3_ca -notext -md sha256 -in intermediate/certs/ca.csr -out intermediate/certs/ca.cert
利用根證書或者中間證書簽發客戶端證書的步驟如下:
- 新建證書密鑰
#新建密鑰
openssl genrsa -out /path/to/server.key 2048
2. 新建證書請求
#新建證書請求
openssl req -new -in /path/to/server.key -out /path/to/server.csr
3. CA簽發證書
#證書CA簽名
openssl x509 -req -in /path/to/server.csr -CA /path/to/ca.crt -CAkey /path/to/ca.key -CAcreateserial -out /path/to/server.crt
4. CA證書的有效性驗證
#驗證證書
openssl verify -CAfile /path/to/ca.crt /path/to/server.crt
#如果結果顯示OK,說明我們頒發的證書是有效的。
不同客戶端證書格式轉換
#crt,pem格式證書可用于linux/nginx/node.js格式客戶端
#p12(pkcs12)格式證書用于tomcat/java/android客戶端
#打包為p12證書
openssl pkcs12 -export -in /path/to/server.crt -inkey /path/to/server.key -out /path/to/server.p12
吊銷證書
當證書已經不再使用或者密鑰泄露時,我們需要吊銷證書來保證服務器的安全。
#獲取要吊銷的證書的serial
openssl x509 -in /path/to/x.crt -noout -serial -subject
#對比serial與subject 信息是否與index.txt中的信息一致
#如果一致,則可以吊銷證書
openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem
#如果是第一次吊銷證書,需要指定吊銷的證書編號
echo 01 >/etc/pki/CA/crlnumber
#更新吊銷證書列表
openssl ca -gencrl -out /etc/pki/CA/crl.pem
#完成后,可查看吊銷的證書列表
openssl crl -in /etc/pki/CA/crl.pem -noout -text