搭建個人國密CA(Certification Authority)

在SSL/TLS/HTTPS通信中,證書雖然不是TLS/SSL協議的一部分,卻是HTTPS非常關鍵的一環,網站引入證書才能避免中間人攻擊。證書涉及了很多密碼學知識,理解證書後,再深入理解TLS/SSL協議,效果會更好。

在前面一篇文章《搭建國密SSL開發測試環境》中,我們製作了一個自簽名證書。通常情況下,用作調試簡單的客戶端/服務器端通信,足夠了。然而,現實世界的證書要複雜的多,涉及到CA、證書鏈、證書的撤銷等多種場景。如果我們要實現一個完善的SSL/TLS/HTTPS就需要把這些場景考慮進去,這時僅僅靠自簽名證書是不夠的。

我們也可以通過CA申請證書,對於個人開發者而言,成本比較高。比如從網上找到的國密證書價格,一年好幾千元到幾萬的都有:

國密證書參考價格

那有沒有辦法自己製作證書呢?答案是可以的。本文將探討使用GmSSL製作國密證書,包括製作自簽名根證書,並使用根證書籤發證書。這樣在開發中可以調試證書鏈的處理流程。

本文所使用的方法在Ubuntu 16.04上驗證通過,在其它linux發行版本上,可能命令需要稍微做一些調整。關於國密SSL環境,請參考:

搭建國密SSL開發測試環境

現實世界的CA是分級管理的,層級可以有多層。本文簡單起見,只模擬到三級CA管理,具體來說:

Root CA -> Server CA -> Server

Root CA爲一級CA,擁有根CA證書,Server CA爲二級CA,其CA證書由Root CA簽發,Server爲最終的用戶,其證書由Server CA簽發。當然,Root CA也可以直接給Server簽發證書,這裏是爲了演示CA層級需要而做的這樣的假定。

製作根CA證書

1. 生成SM2私鑰:

gmssl ecparam -genkey -name sm2p256v1 -text -out rootkey.pem

根證書的私鑰保存在rootkey.pem中,請妥善保存。

2. 創建證書請求:

$ gmssl req -new -key rootkey.pem -out rootreq.pem


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) [CN]:
State or Province Name (full name) [Some-State]:Hubei
Locality Name (eg, city) []:Wuhan
Organization Name (eg, company) [Internet Widgits Pty Ltd]:mogoweb
Organizational Unit Name (eg, p) []:mogoweb
Common Name (e.g. server FQDN or YOUR name) []:mogoweb.com
Email Address []:[email protected]


Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

上面的命令會要求提供一些信息,因爲證書是自簽名證書,只用於開發測試,所以填寫什麼內容無關緊要。

3.創建一個 certext.ext 文本文件,內容爲:

[ v3_ca ]
basicConstraints = CA:true
[ usr_cert ]
subjectAltName = DNS:localhost

注意:相比上一篇文章,這個文件多增加了 "CA:true" 這個擴展,用於指定所簽發的證書是否CA證書。

4. 生成證書:

$ gmssl x509 -req -days 365 -in rootreq.pem -signkey rootkey.pem -extfile certext.ext -extensions v3_ca -out rootcert.pem
Signature ok
subject=C = CN, ST = Hubei, L = Wuhan, O = mogoweb, OU = mogoweb, CN = mogoweb.com, emailAddress = [email protected]
Getting Private key

注意:上面的命令行參數多了一個 -extensions v3_ca 參數,指定使用上面 certext.ext 文件 v3_ca 節的擴展項。

5. 將key和證書合到一個文件中

注意: 這個步驟並非必要,只是爲了開發和調試方便。在實際部署時,私鑰需要小心保存,絕不能和證書一起分發出去!

$ cat rootcert.pem rootkey.pem > root.pem

簽發 Server CA 證書

和上面的步驟一樣,這裏直接把命令總結一下:

$ gmssl ecparam -genkey -name sm2p256v1 -text -out serverCAkey.pem
$ gmssl req -new -key serverCAkey.pem -out serverCAreq.pem
$ gmssl x509 -req -days 365 -in serverCAreq.pem -extfile certext.ext -extensions v3_ca -CA root.pem -CAkey root.pem -CAcreateserial -out serverCAcert.pem
$ cat serverCAcert.pem serverCAkey.pem rootcert.pem > serverCA.pem

需要注意第三個命令多了 -CA 和 -CAkey 參數,表示使用根證書籤名。因爲上面的步驟中,我們把key和證書合成了一個文件,所以這兩個參數值給的同一個文件。

簽發 Server 證書

和上面的步驟一樣,這裏直接把命令總結一下:

$ gmssl ecparam -genkey -name sm2p256v1 -text -out serverkey.pem
$ gmssl req -new -key serverkey.pem -out serverreq.pem
$ gmssl x509 -req -days 365 -in serverreq.pem -extfile certext.ext -extensions usr_cert -CA serverCA.pem -CAkey serverCA.pem -CAcreateserial -out servercert.pem
$ cat servercert.pem serverkey.pem serverCAcert.pem rootcert.pem > server.pem

注意: 第三個命令的 -extensions 給的參數值爲 usr_cert ,對應的是 certext.ext 文件 usr_cert 節的擴展項,通常需要給定服務器的DNS名。

這樣,生成的 server.pem 包含了根證書、Server CA證書和Server證書,包含了完整的證書鏈,可以投入測試使用了。

再次聲明: 將key和證書打包在一起,只是爲了開發和調試方便。在實際部署時,私鑰需要小心保存,絕不能和證書一起分發出去!

問題

1. 自簽名證書出錯

-Error with certificate at depth: 0
 err 18:self signed certificate

原因:CA證書的 Organization Name 值和所簽發的證書的 Organization Name 值相同。

解決方法:重新制作server證書,注意其 Organization Name 值不要和Server CA證書相同。

2. 無效的CA證書

-Error with certificate at depth: 1
 err 24:invalid CA certificate

原因:CA證書的 CA:true 擴展屬性沒加上 解決方法:重新制作root和Server CA證書,注意 CA:true 擴展屬性

小結

本文介紹了搭建個人國密CA的方法,這樣你也可以簽發國密證書了。當然CA的一個重要前提是信任,別人如何信任你簽發的證書?所以個人肯定取代不了CA中心的地位,本文僅僅探討用於開發測試過程中的證書籤發。如果真的需要在產品中部署國密證書,還是需要去指定的CA中心去申請。

如果大家有什麼問題,歡迎交流。

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