OpenSSL(2)創建私有證書頒發機構


  如果想要建立自己的CA, OpenSSL已經包含了所有你需要的東西。所有的操作都通過純命令行執行,雖然不那么友好,整個過程也比較長,但是這可以讓你去思考每個細節。

  我建議自己創建一套私有的 CA主要是出於教學的目的,不過還有一些別的原因。OpenSSL的CA天然滿足個人或者小團體的需求,例如在開發環境使用一套CA比到處使用自簽名的證書好得多。同時還可以通過客戶端證書來提供雙向驗證,這可以極大地提高敏感Web應用的安全性。

  運行私有CA最大的挑戰不是設置問題,而是如何保證基礎結構的安全。例如根密鑰必須離線保存,因為所有的安全都依賴它。另一方面, CRL和OCSP響應程序證書必須定期進行更新,而這會要求根密鑰保持聯機。

功能和限制

我們會創建一個與公共CA類似的私有CA架構。會先有一個根CA,然后創建其他的二級CA。接着我們會通過CRL和OCSP服務提供證書吊銷信息。為了讓根CA的私鑰可以離線保存, OCSP響應程序需要使用它們自己的身份。這並非是最簡單的CA,但是相對來說比較安全。另外二級CA會在技術上進行限制,只能給允許的主機名簽發證書

完成設置之后,必須將根證書安全地分發給所有客戶端。一旦根證書分發完畢,就可以開始簽發客戶端和服務器證書了。有一個限制是以這種方式設置的OCSP響應程序主要用來測試,因為只能承受比較小的負載。

創建根 CA 

創建全新的CA有幾個步驟:配置、創建目錄結構和初始化密鑰文件,最后生成根密鑰和證書。本節描述了整個過程和常見的CA操作。

1)根CA配置

創建CA之前,我們需要先准備一個配置文件告訴OpenSSL我們希望的配置。一般情況下並不需要配置文件,但是根CA的創建操作復雜,使用配置文件可以簡便很多。 OpenSSL的配置文件很強大,在開始之前我建議你熟悉一下這些配置的功能(命令行上使用man config命令)。

配置文件第一部分包括了CA的名稱、基礎URL和CA可分辨名稱等基本信息。因為這些配置都很靈活,只需配置一次即可。

[default]
name = root-ca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9080
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_dn]
countryName = "GB"
organizationName = "Example"
commonName = "Root CA"

第二部分直接控制了CA的操作。有關每個設置的完整信息,可以通過ca命令來獲取它的文檔(命令行上輸入man ca)。大部分命令從字面意思就可以很容易理解,我們需要告訴OpenSSL存放文件的路徑。因為根CA只用作二級CA的簽發,所以我把有效期設置為10年。另外默認情況下使用SHA256作為簽名算法。

默認策略( policy_c_o_match)限制了這張CA簽發的證書的國家名和組織名會與CA本身一樣。對於公共CA來說很少會有這樣的設置,但對於私有CA來說這種方式比較合適:

[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match
[policy_c_o_match]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

第三部包含了req命令的配置, req命令只會在創建自簽發根證書的時候用到一次。最重要的部分是擴展:基本限制( basicContraints)擴展表明這個證書是一張CA,密鑰用法( keyUsage)擴展用來說明這個CA的用處:

[req]
default_bits = 4096
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash

配置的第四部分包括了根CA創建證書所需要的信息。因為基本限制( basicContraints)擴展的設置,所有的證書都將成為CA,但是我們需要把pathlen設置為0,表示這些CA無法再簽發新的CA了。

所有二級CA都會受到限制,也就是說他們簽發的證書只能對一些域名的子集有效,並且會被限制使用場景。第一,擴展密鑰用法( extendedKeyUsage)擴展限制了只能進行客戶端驗證( clientAuth)和服務器驗證( serverAuth),也就是TLS的客戶端和服務器驗證。第二,名稱限制( nameContraints)擴展限制了允許簽發的域名只有example.com和example.org。理論上這樣的設置讓你可以簽發二級CA給第三方,同時可以通過限制他們無法簽發任意域名的主機名來保證安全。排除這兩個IP段的要求來自CAB論壇的Baseline Requirements,該規范從技術上定義了對二級CA的限制。

實際上,名稱限制( nameContraints)並不完美,因為當前還有很多主流的平台無法識別名稱限制擴展。如果你將這個擴展標記為關鍵擴展,就會導致很多平台拒絕識別你的證書。如果將其標記為關鍵擴展,那么很多平台就不會識別這個擴展,導致名稱限制實際沒有任何效果。

[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
nameConstraints = @name_constraints
subjectKeyIdentifier = hash
[crl_info]
URI.0 = $crl_url
[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url
[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0

最后兩部分的配置表示有了這個擴展的證書可以對OCSP響應進行簽名。為了能夠運行OCSP響應程序,我們生成一個特別的證書,並且將OCSP的簽名能力賦予這張證書。從擴展可以看出這張證書不是一個CA:

[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash

2)根CA的目錄結構

下面我們會創建“根CA配置”中說到的目錄結構,並且會初始化一些CA操作中會用到的文件。

$ mkdir root-ca
$ cd root-ca
$ mkdir certs db private
$ chmod 700 private
$ touch db/index
$ openssl rand -hex 16 > db/serial
$ echo 1001 > db/crlnumber
我們會用到以下這幾個目錄。
 certs/
存放證書的地方;證書在簽名之后會放置到這個目錄下。
 db/
這個目錄用於證書數據庫( index),一些包括下一張證書以及CRL數字的文件。 OpenSSL
會創建額外需要的一些文件。
 private/
這個目錄會存放私鑰,一個給CA使用,一個給OCSP響應程序使用。務必確保其他用戶
都不能訪問這個目錄(事實上,如果你真的很在意這個CA,那么這台存放根證書和密鑰
的服務器的用戶賬戶必須盡可能少)。

3)CA生成

我們需要分兩步來創建根CA。首先,我們生成密鑰和CSR文件。當我們使用-config開關之后,所有需要的信息都會從配置文件中加載進來

$ openssl req -new \
-config root-ca.conf \
-out root-ca.csr \
-keyout private/root-ca.key

第二步我們會創建自簽名證書。 -extension開關指向了配置文件的ca_ext部分,這樣可以激活根CA所需的擴展。

$ openssl ca -selfsign \
-config root-ca.conf \
-in root-ca.csr \
-out root-ca.crt \
-extensions ca_ext

4)數據庫文件結構 

db/index中的數據庫是一個包含證書信息的明文文件,每行一個證書。我們剛剛創建根CA,現在這個文件只有一行信息

V 240706115345Z 1001 unknown /C=GB/O=Example/CN=Root CA

每一行包括以下6個以制表符分隔的值。

(1) 狀態標記[ V表示有效( valid), R表示已吊銷( revoked), E表示已過期( expired)]
(2) 過期時間(以YYMMDDHHMMSSZ格式表示)
(3) 吊銷日期,如果沒有被吊銷則為空
(4) 序列號(十六進制)
(5) 文件路徑(如果不知道就顯示unknown)
(6) 可分辨名稱

5)CA操作

使用ca命令的-gencrl開關給新CA生成CRL

$ openssl ca -gencrl \
-config root-ca.conf \
-out root-ca.crl

使用ca的的命令來簽發證書。需要注意的是-extensions開關需要指向配置文件里面正確的部分(例如,你肯定不希望再生成另一個根CA)。

$ openssl ca \
-config root-ca.conf \
-in sub-ca.csr \
-out sub-ca.crt \
-extensions sub_ca_ext

  如果要吊銷證書,可以使用ca命令的-revoke開關,不過需要有一份你想吊銷的證書的副本。不過因為所有的證書都存在certs/目錄下,所以只需要知道序列號即可。如果知道證書的可分辨名稱,就可以在數據庫里面查到它的序列號了。
  為-crl_reason開關中的值選擇一個正確的理由。該值可以是以下這些值之一: unspecified、keyCompromise 、 CACompromise 、 affiliationChanged 、 superseded 、 cessationOfOperation 、certificateHold和removeFromCRL。

$ openssl ca \
-config root-ca.conf \
-revoke certs/1002.pem \
-crl_reason keyCompromise

6)創建用於OCSP簽名的證書

首先我們需要給OCSP響應程序創建一個私鑰和CSR。這兩個操作對所有的非CA證書都適用,所以不需要指定配置文件:

$ openssl req -new \
-newkey rsa:2048 \
-subj "/C=GB/O=Example/CN=OCSP Root Responder" \
-keyout private/root-ocsp.key \
-out root-ocsp.csr

第二步需要使用根CA簽發一張證書。 -extensions開關的值選擇ocsp_ext,以確保設置了OCSP簽名所需要的擴展。我將這個證書的生命周期減少為365天(原來默認是3650天)。這些OCSP證書是沒有吊銷信息的,所以無法吊銷它們。因此你會希望盡可能減少它們的生命周期。 30天是一個比較好的選擇,當然前提是你已經准備好頻繁地創建新的OCSP證書。

$ openssl ca \
-config root-ca.conf \
-in root-ocsp.csr \
-out root-ocsp.crt \
-extensions ocsp_ext \
-days 30

現在你已經有了OCSP響應程序所需要的一切東西,可以直接在根CA所在的服務器上進行測試。當然,如果在生產環境中使用,就必須將OCSP響應程序的密鑰和證書放到別的地方

$ openssl ocsp \
-port 9080
-index db/index \
-rsigner root-ocsp.crt \
-rkey private/root-ocsp.key \
-CA root-ca.crt \
-text

可以使用下面的命令來測試OCSP響應程序:

$ openssl ocsp \
-issuer root-ca.crt \
-CAfile root-ca.crt \
-cert root-ocsp.crt \
-url http://127.0.0.1:9080

輸出結果中的verify OK表示已經成功驗證簽名,而good表示這張證書還沒有被吊銷。

Response verify OK
root-ocsp.crt: good
This Update: Jul 9 18:45:34 2014 GMT

創建二級 CA

創建二級CA的過程和根CA幾乎完全一樣。

1)二級CA配置

我們可以在前面根CA配置文件的基礎上,進行一些適當的修改生成二級CA的配置。我們會把名稱改為sub-ca並且使用另一個可分辨名稱。我們將二級CA的OCSP響應程序放在另外一個端口,主要是因為ocsp命令不識別虛擬主機。如果為OCSP響應程序使用了適合的Web服務器,就可以完全避免使用特別的端口。該證書默認的生命周期是365天,我們會每隔30天生成全新的CRL。

將copy_extensions更改為copy意味着在生成新證書的時候,如果我們的配置文件里面沒有設置某些擴展,那么就會使用CSR文件里面的擴展字段。進行此更改之后,在准備CSR文件的時候就可以加入別的一些需要的字段,這些信息會在生成證書的時候加入到證書里面。這個特性有幾分危險(因為允許其他人可以在一定程度上直接控制證書里面的內容),不過我認為在較小的環境中這么做是可以的。

[default]
name = sub-ca
ocsp_url = http://ocsp.$name.$domain_suffix:9081
[ca_dn]
countryName = "GB"
organizationName = "Example"
commonName = "Sub CA"
[ca_default]
default_days = 365
default_crl_days = 30
copy_extensions = copy

在配置文件的最后面,我們會增加兩個新的配置,分別用於服務器和客戶端證書的生成。唯一的區別就是keyUsage和extendedKeyUsage擴展。注意到我們把basicContraints擴展的值設置為false。之所以這么做,原因在於我們會復制CSR文件里面的擴展。如果在配置文件中沒有顯示設置這個擴展,那么就可能會用到CSR文件中的basicContraints了。

[server_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier = hash
[client_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash

改好配置文件之后,按照根CA的過程創建一個同樣的目錄結構,不過可以使用另外一個名稱,比如sub-ca。

2)二級CA生成

與前面一樣,創建二級CA需要兩步。第一步生成密鑰和CSR。當我們使用-config開關的時候,所有需要的信息都會從配置文件中加載進來。

$ openssl req -new \
-config sub-ca.conf \
-out sub-ca.csr \
-keyout private/sub-ca.key

第二步我們使用根CA來簽發證書。 -extensions開關指向配置文件中的sub_ca_ext,從而使用二級CA所需要的擴展。

$ openssl ca \
-config root-ca.conf \
-in sub-ca.csr \
-out sub-ca.crt \
-extensions sub_ca_ext

3)二級CA操作

要簽發服務器證書,可以在處理CSR文件的時候,在-extensions開關中指定server_ext

$ openssl ca \
-config sub-ca.conf \
-in server.csr \
-out server.crt \
-extensions server_ext

要簽發客戶端證書,可以在處理CSR文件的時候,在-extensions開關中指定client_ext

$ openssl ca \
-config sub-ca.conf \
-in client.csr \
-out client.crt \
-extensions client_ext
注意
當收到新證書申請請求的時候,你需要在對所有信息進行驗證之后才能進行操作。你
需要確保所有資料符合規定,特別是當你處理的CSR文件是別人生成的時。特別要注
意證書的可分辨名稱以及basicContraints和subjectAlternativeName擴展。

二級CA的CRL生成和證書的吊銷過程與根CA是一樣的。唯一不同的是OCSP響應程序所使用的端口;二級CA使用的是9081端口。推薦OCSP響應程序使用獨立的證書,這樣可以避免將二級CA部署到公開的服務器上.

 

本文摘自《OpenSSL攻略》 

詳細操作擴展https://www.cnblogs.com/sparkdev/p/10369313.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM