一般情況下我們使用的證書都是由第三方權威機構來頒發的,如果我們有一個新的https網站,我們需要申請一個世界範圍內都獲得認可的證書,這樣我們的網站才能被無障礙的存取。
如果在某些情況下,我們的網站或者系統並不是公開的,但是也需要使用tls協定的話,那麼就需要自己搭建一個CA伺服器。這樣的CA伺服器就叫做private CA。
熟悉證書的朋友可能會說了,為什麼不使用自簽名證書呢?也可以達到安全通訊的目的。
這是因為自簽名證書的作用比較有限,它沒有CRL和OCSP的能力,並且使用起來也不是很方便。所以我們需要一整套有效的CA簽發體系,這也是我們需要搭建private CA的目的。
在搭建root CA之前我們需要建立幾個合適的目錄來儲存CA的相關資訊,比如我們需要一個儲存證書的目錄certs,一個儲存金鑰的地方keys,一個CA資料庫db。
其中db需要一個index檔案,serial檔案和crlnumber檔案。
我們用下面的命令建立對應的檔案和目錄:
mkdir certs db keys
touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber
目錄建好之後,我們還需要一個非常重要的root ca組態檔。後續可以根據這個組態檔來建立CA相關的資訊。
一般情況下CA組態檔是不需要的,只有我們需要建立比較複雜CA的情況下才需要使用ca組態檔。
下面是一個CA組態檔的例子:
[default]
name = root-ca
domain_suffix = flydean.com
default_ca = ca_config
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_config]
database = db/index
serial = db/serial
crlnumber = db/crlnumber
certificate = root-ca.crt
private_key = keys/root-ca.key
RANDFILE = keys/random
new_certs_dir = certs
unique_subject = no
copy_extensions = none
default_days = 365
default_crl_days = 100
default_md = sha256
policy = ca_policy
[ca_policy]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 4096
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dist
req_extensions = ca_req_ext
[ca_dist]
countryName = "CN"
organizationName = "flydean"
commonName = "Root CA"
[ca_req_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[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
subjectKeyIdentifier = hash
[crl_info]
URI.0 = http://crl3.digicert.com/DigiCertTLSRSASHA2562020CA1-4.crl
[issuer_info]
caIssuers;URI.0 = http://cacerts.digicert.com/DigiCertTLSRSASHA2562020CA1-1.crt
OCSP;URI.0 = http://ocsp.digicert.com
[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
noCheck = yes
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
有了上面的組態檔和目錄資訊,就可以生成root CA了。
首先我們需要建立私鑰和root ca的csr檔案如下:
openssl req -new -config root-ca.conf -out root-ca.csr -keyout keys/root-ca.key
接下來我們建立一個自簽名的證書,這裡我們需要用到組態檔中的ca_req_ext部分:
openssl ca -selfsign -config root-ca.conf -in root-ca.csr -out root-ca.crt -extensions ca_req_ext
執行該命令之後,我們會在certs資料夾中建立一個自簽名證書檔案。
除此之外,還向db中的index檔案中寫入了下面的內容:
V 230501041451Z 4445DE5C0285EAEF2E58757D5CB1E949 unknown /C=CN/O=flydean/CN=Root CA
這是一個文字檔案,裡面儲存的是生成的證書索引,證書中的欄位是通過tab來進行分割的。
第一個欄位V表示valid也就是有效的意思,這個欄位還可以有其他幾個值,比如R表示revoked,E表示expired。
第二個欄位是過期時間,格式是YYMMDDHHMMSSZ。
第三個欄位是Revocation日期,如果空表示沒有revoked。
第四個欄位是序列號,也就是生成的CA名字。
第五個欄位是檔案的位置,unknown表示未知。
最後一個欄位是這個證書的名字,用於和其他的證書做區分。
有了root-ca.conf之後,我們可以使用它來建立CRL:
openssl ca -gencrl -config root-ca.conf -out root-ca.crl
現在生成的root-ca.crl檔案還沒有任何證書資訊。
如果我們想要復原某個頒發的CA,可以使用下面的命令:
openssl ca -config root-ca.conf -revoke certs/torevoke.pem -crl_reason unspecified
在revoke中指定要revoke的證書即可。
這裡要注意的是我們需要指定crl_reason,crl_reason可以是下面幾個值:
unspecified
keyCompromise
CACompromise
affiliationChanged
superseded
cessationOfOperation
certificateHold
removeFromCRL
對於OSCP來說,需要一個OCSP responder來響應OCSP的請求。這個OCSP responder和CA本身並不是同一個,需要單獨建立。
首先,我們建立OCSP responder的key和證書請求CSR:
openssl req -new -newkey rsa:2048 -keyout keys/root-ocsp.key -out root-ocsp.csr
當然輸入必須的引數之後,key和CSR就可以生成了。
接下來我可以使用root CA和root-ocsp.csr頒發OCSP證書,這裡我們需要用到組態檔中的ocsp_ext部分。
openssl ca -config root-ca.conf -in root-ocsp.csr -out root-ocsp.crt -extensions ocsp_ext -days 10
上面的命令為OCSP responder生成了一個有效期為10天的證書。
有了證書,我們可以方便的搭建一個原生的OCSP responder如下所示:
openssl ocsp -port 9000 -index db/index -rsigner root-ocsp.crt -rkey keys/root-ocsp.key -CA root-ca.crt -text
Enter pass phrase for keys/root-ocsp.key:
Waiting for OCSP client connections...
這樣我們就啟動了一個OCSP伺服器端。
另開一個視窗,執行下面的命令來請求OCSP:
openssl ocsp -issuer root-ca.crt -CAfile root-ca.crt -cert root-ocsp.crt -url http://127.0.0.1:9000
可以得到下面的結果:
Response verify OK
root-ocsp.crt: good
This Update: May 1 08:09:31 2022 GMT
這就說明OCSP responder搭建成功了。
這裡啟動的是一個本地服務,在正式環境中可以考慮將其遷移到單獨的伺服器中。
使用上面的命令,我們搭建了一個私有的CA服務,和對應的OCSP,openssl非常強大,基本上你可以用他來做任何事情。
更多內容請參考 http://www.flydean.com/45-openssl-private-ca/
最通俗的解讀,最深刻的乾貨,最簡潔的教學,眾多你不
歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!