在密碼學中,CA(Certificate Authority,認證機構)是指一個被多個用戶信任的機構,該機構能夠創建和指派公鑰證書。
為規范起見,我們先介紹本文可能涉及的術語,
asymmetric cryptography: 非對稱密碼學(或公開密鑰加密,公鑰加密),密鑰涉及公鑰和私鑰組成的密鑰對;
key pair: 密鑰對,非對稱密碼學中的一對公/私密鑰;
private key: 私鑰,只應該有所有者才知道的那個密鑰;
public key: 公鑰(公開密鑰),在非對稱加密體系中公開給其他用戶的的密鑰;
public key certificate:公開密鑰證書,由認證機構采用自己的私鑰進行數字簽名后的用戶公鑰證書,包含用戶的公鑰和身份信息,用於確認公鑰證書持有者的身份;
CA: 認證機構,能夠頒發公開密鑰證書的機構;
PKI: 公開密鑰基礎設施(public key infrastructure);
許多涉及電子交易或電子轉賬的網站都需要確保用戶安全地連接到自己網站。為了達到這一目的,這些單位需要由一些國際認可的CA(如,VeriSign等)來為自己頒發公鑰證書。這些證書被用於建立SSL連接或解密電子簽名等用途。申請證書的過程需要經過CA的實地認證,同時為CA支付不菲的認證費用。
對於僅僅搭建一個VPN或內網環境的應用場景,這樣的開銷與周期顯然是不必要的,因此在一些特定環境下我們只需要自己為自己頒發的公鑰證書即可。本文就介紹如何擔任自己的CA也即是自己“創辦”一個實驗的CA機構。
本文中我們采用/etc/pki/CA作為保存私鑰和公鑰證書的根目錄,為了方便起見下文統稱該目錄為“證書根目錄”。
我們的實驗環境是Ubuntu 14.04 LTS, 但在其他的Linux平台上也應該同樣適用,操作系統需要安裝OpenSSL,同時該部分的操作要以系統管理員的身份進行,因此下文中的命令行統一采用"#"標識符打頭。
在安裝OpenSSL后,系統會在/etc/ssl/目錄下生成openssl.cnf文件(不同的操作系統可能位於不同的目錄),我們后面需要用到這個文件。
首先我們要在證書根目錄下創建一些子目錄,為了后續操作的方便,這些目錄的命名遵循openssl.cnf的命名方式,還要在證書根目錄下創建index.txt和serial文件用於追蹤密鑰和證書的記錄:
# mkdir /etc/pki/CA
# cd /etc/pki/CA
# mkdir certs crl newcerts private
# chmod 700 private
# touch index.txt
# echo 1000 > serial
上面的指令在我們的證書根目錄下創建了四個新目錄和兩個追蹤文檔,在創建完目錄后及時更改權限是一個很好的習慣。
這里private/目錄將存放我們未來創建的CA根私鑰,該私鑰需要受到嚴格保護,一旦該私鑰泄露,任何獲得該私鑰的人員均可以利用其創建證書,所以下文中我們將對其進行加密。
同時,如果將本文的操作應用於小型生產或局域網環境,理想的情況是在生成該目錄中的CA根私鑰前斷開網絡連接,將生成后的內容保存到不接入網絡的存儲介質如U盤等,只有在后續需要使用的時候再連入主機。
接下來我們要生成自己的CA私鑰,下面的命令采用AES-256算法加密CA根私鑰,將其保存在private/ca.key.pem文件中,為避免誤改,將文件置為只有管理員可讀的狀態。
由於選擇了加密CA私鑰,在生成該私鑰時要求輸入使用密碼,該密碼用於在后續使用CA根私鑰時解密獲得CA私鑰,因此該密碼應由創建CA私鑰的輸入並妥善保存。
# openssl genrsa -aes256 -out /etc/pki/CA/private/ca.key.pem 4096
Enter pass phrase for ca.key.pem:SECRET
Verifying - Enter pass phrase for ca.key.pem:SECRET
# chmod 400 /etc/pki/CA/private/ca.key.pem
接下來我們利用OpenSSL為自己創建公鑰證書,假設保存為ca.cert.pem,首先進行公鑰證書創建前的配置,
# cd /etc/pki/CA # cp /etc/ssl/openssl.cnf root_CA.cnf # vim root_CA.cnf
模板中的配置項需要進行適當的修改,確保以下字段被設置:
[ CA_default ]
dir = /etc/pki/CA
certs = $dir/certs
private = $dir/private
certificate = $certs/ca.cert.pem
private_key = $private/ca.key.pem
[ usr_cert ] # CA簽名時常用的擴展 basicConstraints=CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer [ v3_ca ] # CA的一些典型擴展 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = CA:true keyUsage = cRLSign, keyCertSign
接下來創建公鑰證書,
# cd /etc/pki/CA
# openssl req -new -x509 -days 3650 -key private/ca.key.pem \
-sha256 -extensions v3_ca -out certs/ca.cert.pem \
-config root_CA.cnf
上面的一條命令指定了我們要為之前創建的CA根私鑰頒發公鑰證書,該證書的有效期是10年,采用SHA-256算法生成消息摘要,同時由於這是一個CA證書,需要在命令中指明采用v3_ca擴展,該擴展的具體配置已經在root_CA.cnf文件中設置,采用-config選項包括配置文件。
該命令執行后首先要求我們輸入前文中設置的CA私鑰密碼,還需要聲明自己的一些身份信息:
Enter pass phrase for ca.key.pem: You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:Beijing Locality Name (eg, city) [Default City]:Beijing Organization Name (eg, company) [Default Company Ltd]:Alice CA Organizational Unit Name (eg, section) []:Certificate Authority Common Name (eg, your name or your server's hostname) []:Alice CA Email Address []:alice@example.com
當這些信息輸入完成后,生成的公鑰證書ca.cert.pem就導入到certs/目錄下了。
這樣我們就自己創建了一個CA,擁有了該CA的私鑰和公鑰證書,接下來,我們可以直接使用這個CA私鑰和證書簽名和頒發客戶證書,也可以利用該根私鑰和公鑰證書創建中間認證機構,中間認證機構是我們這里CA的代理,能夠代表我們剛創建的CA簽發客戶證書。創建中間CA的優點在我們不使用CA根私鑰而是使用中間CA的私鑰來簽發客戶證書,CA根私鑰只用來簽發中間CA的證書撤銷列表,這樣能夠更為妥善地保護CA根私鑰。
下面的一篇隨筆介紹如何使用根CA創建中間CA並為其頒發證書;
也可以直接利用本文中生成的私鑰和證書頒發用戶證書。