使用OpenSSL實現CA證書的搭建過程
什麼是CA
CA,Catificate Authority,通俗的理解就是一種認證機制。它的作用就是提供證書(也就是服務端證書,由域名,公司資訊,序列號,簽名信息等等組成)來加強客戶端與伺服器端訪問資訊的安全性,同時提供證書的發放等相關工作。國內的大部分網際網路公司都在國際CA機構申請了CA證書,並且在使用者進行訪問的時候,對使用者的資訊加密,保障了使用者的資訊保安。理論上來說,任何組織或者個人都可以扮演CA的角色,只不過,難以得到客戶端的信任,不能推而廣之,最典型應用莫過於12306網站,這個網站就是自己給自己頒發的根證書。
目前能夠讓瀏覽器預設支援的CA大廠有很多,Windows 作業系統在安裝之初,也預設安裝了很多受信任的根證書。可以通過控制面板–Internet選項來進行檢視。
SSL/TLS
SSL/TLS是網路通訊過程中非常重要的兩個協議。網際網路的通訊安全就建立在SSL/TLS協議基礎之上。他們通過一系列的加密行為保障了通訊的安全,是如今網際網路通訊最主要的應用之一。
SSL/TLS是一個很大的網際網路應用,關於他們的介紹網際網路上有很多,我們暫時不做詳細的介紹。關於SSL/TLS通訊的過程大致可以用下面的這張圖來進行描述。
OpenSSL
OpenSSL是一套開源軟體,在Linux中可以很容易的安裝。它能夠很容易的完成金鑰生成以及證書管理。我們接下來就利用OpenSSL搭建CA證書,並實現證書的申請與分發。
OpenSSL實現CA證書的搭建
- 實驗環境的準備
- CA的配置介紹
- 建立所需要的檔案
- CA 自簽名證書
- 頒發證書
- 檢視證書狀態
- 證書吊銷
實驗環境的準備
首先我們應該準備三個虛擬機器,他們分別用來表示根CA證書機構,以及子CA證書機構,和證書申請使用者。
那麼問題來了,使用者向子CA證書機構申請證書,子CA機構向根CA機構申請授權,根CA是如何取得證書的呢?答案是根CA自己給自己頒發的證書。
實驗環境的拓撲結構如下圖所示。
CA配置介紹
要手動建立CA證書,就必須首先了解,OpenSSL中關於CA的配置,配置檔案位於下面的/etc/pki/tls/openssl.cnf
####################################################################
[ ca ]
default_ca= CA_default #預設CA
####################################################################
[ CA_default ]
dir=/etc/pki/CA # CA的工作目錄這裡其實是定義了一個變數
certs= $dir/certs # 證書儲存路徑
crl_dir= $dir/crl # 證書吊銷列表
database= $dir/index.txt # 證書資料庫列表
new_certs_dir= $dir/newcerts #新的證書路徑
certificate = $dir/cacert.pem # CA自己的證書
serial= $dir/serial #下一個證書的編號,十六進位制,預設00
crlnumber= $dir/crlnumber #下一個要被吊銷的證書編號,十六進位制,預設00
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # CA 的私鑰
RANDFILE= $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # 命名方式
cert_opt = ca_default # CA的選項
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions= crl_ext
default_days= 365 # 預設證書的有效期限
default_crl_days= 30 # how long before next CRL
default_md= default # use public key default MD
preserve= no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy= policy_match #策略
#這裡記錄的是 將來CA在搭建的時候,以及客戶端申請證書的時候,
需要提交的資訊的匹配程度。
# For the CA policy
[ policy_match ] # match意味著CA以及子CA必須一致
countryName = match # 國家
stateOrProvinceName= match # 州或者省
organizationName= match #組織公司
organizationalUnitName = optional
commonName= supplied
emailAddress= optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ] #可以對外提供證書申請,這時,證書的匹配就可以不用那麼嚴格
countryName = optional
stateOrProvinceName = optional
localityName= optional
organizationName= optional
organizationalUnitName = optional
commonName = supplied
emailAddress= optional
建立所需要的檔案
這裡有一點需要注意,我們的實驗環境中包含了三個主機,其中兩個的角色是作為CA認證機構存在的,所以建立所需要的檔案的時候,主機A和主機B都需要建立。
如果不提前建立這兩個檔案,那麼在生成證書的過程中會出現錯誤。
我們將檔案建立在配置檔案中指定的路徑下面。
- 生成證書索引資料庫檔案
touch /etc/pki/CA/index.txt
- 指定第一個頒發證書的序列號
echo 01 > /etc/pki/CA/serial
CA 自簽名證書(構造根CA)
首先構造根CA的證書。因為沒有任何機構能夠給根CA頒發證書,所以只能根CA自己給自己頒發證書。
首先生成私鑰檔案
私鑰檔案是非常重要的檔案,除了自己本身以外,其他任何人都不能取得。所以在生成私鑰檔案的同時最好修改該檔案的許可權,並且採用加密的形式進行生成。
# 執行命令生成私鑰檔案。
# 採用了des3的方式對私鑰檔案進行了加密
# 同時臨時指定了umask ,使得生成的私鑰檔案只對自己具有讀寫許可權。
[root@localhost ~]#(umask 066;openssl genrsa -out /etc/pki/CA/private/cakey.pem -des3 2048 )
Generating RSA private key, 2048 bit long modulus
...............+++
.......................................+++
e is 65537 (0x10001)
Enter pass phrase for /etc/pki/CA/private/cakey.pem: #這裡需要輸入密碼
Verifying - Enter pass phrase for /etc/pki/CA/private/cakey.pem: #這裡確認密碼
# 檢視一個生成的私鑰檔案,就會發現已經被加密了
[root@localhost ~]#cat /etc/pki/CA/private/cakey.pem
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,A4FB61EACD1544F2
9JrKVEPhnWhx1W+W1V4PdIvVHNDwb8mb0JYILvXZKc07gvNcYKIlvUoTxjtihbpk
wYQcVm0Z6b2+fjZBXVVR9igFB2OOE74BnSNMsbfPTs5W/SwWLxv0R6x0SbiZ8v/7
D6Qh3u/rXmOQWWTvQnLzh6JaT00c8zgUnn48vMev17Xyg32oJqKqJVL5RNBGmJur
6CaWX8mB5q+HYiBUXzNLQp9T3HNGcnmDNyk0gylEvjeJo3Hq+IOAkjfJE4sYO9ER
tQtsLViFUc5jXX7p0nIO0ANwE7zdjBt9I4aXknZiC4rFYJJtNSa1Wrhoo/MhuwWH
zjc4UyoB1C71sbq2LMgeElHhXN/TfqWGfXFqhkyBJwgrmzQibOJSFeWHZNurILof
UwgNLlABmazvIL5Ps6LgZtyrO2ODSDTzPiCO7kQ0S3mTHYk9+WEeEyMb4uum6oAx
oCofADL0wea+5mHVUA2s6KwRBFr01HiQ00fiul6LFvXdCwt9IL62blIJYn2veQHl
oPvC5cTnPVqJ28GJWbPvJjiOLB8Hh+4DPwxaRA1eYf2R9SR0R1SYJIBTI6NNqNwW
Lq+pD89bGCbFdYID+kAZfG27FonmmLvvhTn3jQKVPpwQBROHQ9gpwMLnpmpJWwNK
byUSit+Vt+mvbzOLjuTdsTzklwZEOkNpaE/jTqusWuhXS33D4bqA+Ws+xNVDnx6e
rbrGcbX9skXyti21oEIYem0H37ZS2fV9z+/CM/55maOX5xNVQ4aDxWuiMyyUd03D
nhhM5A4mcDvIZLpWDbHzjtkl2H9Pnb9fvGzOIOm7lVQrX8BdidpWjwGTLYG/zUX5
i9NimSnoiqgkhEYl8KXzbnMfD4hX69BXI7le5HAaS38wDKPsmRRW/dgGfRNKzfTZ
qmBimscMsllz21QnG9eqineFDdexGZw1oEQsHp2CivtEwaIKTqOZfNiwHJvm1cbz
M0NOgs+r2qze0czV9dTqM5pVND1Iac1DXYflYZ9g54riQNre/sHp1qpdNQHRRMTP
yTFnGsEfWmI4V4HiSrdQpyHIrnFUryse9kJmRKDfQK7icUf5/KrOD4FOS5zsHrep
/cE14w7s0Zqko9upkYQNBys5TbBmAK8yVJ/Zq7jU3qjDxkYNddpOt8k33vl9CG53
OeWxcWOzJCHIOjakJlLnS+XitsSY4hzUlfEO0/Ffi99zyHXybNPws5Og4KNfgcqW
ReG943oKc5qplfST2tr0K10ipD3WoV+lMbLugrwhfmVOyHGypfJhUMU0oKEjYPP3
JjHSiW0hrnNvrPQ4/mqSps3LyWYZWvH40N88U6dbxgbUgamXLHWtzJdyfBNii8uH
obtye7oeYpAzx0hNurXhpSoswFbxwU5u80eL0/YkfkzkL1P9vtMvDUw/TVNbwHVg
kTS9WEQA52XLMBtanzRzLGJVIXX6ODGgXt2Gql3KO1p43OyZq4Ksvyj8NuvdmBdO
y9SrMvv+cdOMmTkj4nmGBjqSDeFmrSSQf0HoUbfXXXw/RIW/gkcm4qPmNJXUolYp
WBOg5jT78pcJ2sRwb6YQDgC5HleBwuZujixUlKgdZxF1DEpJNBFnNDxq8yKadEzB
-----END RSA PRIVATE KEY-----
生成自簽名證書
私鑰檔案是非常重要的檔案,除了自己本身以外,其他任何人都不能取得。所以在生成私鑰檔案的同時最好修改該檔案的許可權,並且採用加密的形式進行生成。
# 呼叫命令生成一個簽名證書
# 生成證書的過程中需要輸入之前設定的私鑰的密碼
# -new: 生成新證書籤署請求
# -x509: 專用於CA生成自簽證書
# -key: 生成請求時用到的私鑰檔案
# -days n:證書的有效期限
# -out /PATH/TO/SOMECERTFILE: 證書的儲存路徑
[root@localhost ~]#openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out /etc/pki/CA/cacert.pem
Enter pass phrase for /etc/pki/CA/private/cakey.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) [XX]:CN
State or Province Name (full name) []:shandong
Locality Name (eg, city) [Default City]:qingdao
Organization Name (eg, company) [Default Company Ltd]:pojun.tech
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:ca.pojun.tech
Email Address []:
頒發證書
頒發證書這裡我們將分成兩個環節介紹,分別是 子CA證書機構向根CA證書機構申請證書以及普通使用者向子CA證書機構申請證書。
子CA證書機構向根CA申請證書
A 在需要使用證書的主機上生成證書請求
首先在B主機上生成私鑰,這一個過程與前面根CA機構生成私鑰的過程是一致的。
# 這次我們修改了私鑰的長度
# 並且沒有采用加密的方式生成
# 因為主機B是要作為子CA機構的形式存在,他也是一個CA,所以生成私鑰的時候,就應該按照配置檔案中指定的內容,生成cakey.pem
[root@centos6 pki]$(umask 066; openssl genrsa -out /etc/pki/CA/private/cakey.pem 1024)
Generating RSA private key, 1024 bit long modulus
......++++++
..............++++++
e is 65537 (0x10001)
# 檢視私鑰檔案可以發現,沒有了加密的標識
# 同時因為生成時指定了1024的長度,私鑰的長度明顯的變短了。
[root@centos6 ~]$cat /etc/pki/CA/private/cakey.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCxLyAKQCkysisrsuou6oJFJHs/Gk9L406x6sON1a2JX3516FJ2
·····中間省略······
R1ogCVEZq36sgNYUwaT55gLKk5Ik5T6YQimy0bsvo5oQuw==
-----END RSA PRIVATE KEY-----
利用私鑰檔案,生成證書申請檔案。
# 其實這裡的時間是沒有必要指定的。
# 因為證書的時間,是由頒發機構指定的,因此申請機構填寫了時間也沒用
# 其中有些資訊必須要與根證書的內容相同因為在根證書的openssl.cnf檔案中已經指定。
[root@centos6 tls]$openssl req -new -key /etc/pki/CA/private/cakey.pem -days 3650 -out /etc/pki/tls/subca.csr
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) [XX]:CN
State or Province Name (full name) []:shandong
Locality Name (eg, city) [Default City]:qingdao
Organization Name (eg, company) [Default Company Ltd]:pojun.tech
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:subca.pojun.tech
Email Address []:
# 這裡的兩步 預設也可以不用填
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:magedu.com
B 將證書的申請檔案,傳遞給根CA
將前一步生成的證書的申請檔案,傳遞給根CA機構
# 最好將申請檔案,傳輸到指定的目錄下,這樣便於管理
[root@centos6 tls]$scp /etc/pki/tls/subca.csr 172.18.253.127:/etc/pki/CA
C CA頒發證書
此時切換到根CA主機,生成證書
# 這裡的時間必須要進行指定。這時證書頒發機構指定的證書的有效期。
#
[root@localhost CA]#openssl ca -in /etc/pki/CA/subca.csr -out /etc/pki/CA/certs/subca.crt -days 3650
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Sep 11 14:38:13 2017 GMT
Not After : Sep 11 14:38:14 2018 GMT
Subject:
countryName = CN
stateOrProvinceName = shandong
organizationName = pojun.tech
organizationalUnitName = opt
commonName = subca.pojun.tech
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
DB:3E:9C:F4:F4:E9:42:15:00:E7:35:52:FE:04:9A:48:8C:BD:1A:1B
X509v3 Authority Key Identifier:
keyid:01:17:F1:CB:91:4B:20:AD:C7:DF:13:05:A4:D8:83:B2:AB:75:D1:05
Certificate is to be certified until Sep 11 14:38:14 2018 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
#此時檢視index.txt 檔案中,會看到增加了一條新的記錄。
[root@localhost CA]#cat index.txt
V 180911143814Z 01 unknown /C=CN/ST=shandong/O=pojun.tech/OU=opt/CN=subca.pojun.tech
D 將根CA生成的證書頒發給請求者
# 主機B是作為子CA機構存在的,所以證書檔案,必須是cacert.pem,否則,子CA將不能夠給其他使用者頒發證書。
[root@localhost CA]#scp /etc/pki/CA/certs/subca.crt 172.18.250.114:/etc/pki/CA/cacert.pem
普通使用者向子CA機構,申請證書
這一個過程,與子CA向根CA申請證書的過程是類似的。我們將命令的記錄如下
#生成私鑰檔案
# 因為是普通使用者,所以生成的私鑰檔案應該與之前的cacert.pem 有所區別
[root@localhost ~]# (umask 066; openssl genrsa -out /etc/pki/tls/private/app.key 1024)
#利用私鑰檔案,生成證書申請檔案
[root@localhost ~]# openssl req -new -key /etc/pki/tls/private/app.key -out /etc/pki/tls/app.csr
# 將證書申請檔案傳送給 子CA證書頒發機構
[root@localhost ~]# scp /etc/pki/tls/app.csr 172.18.250.114:/etc/pki/CA
# 切換到子CA證書頒發機構
# 子CA證書頒發機構頒發證書
[root@centos6 CA]$openssl ca -in /etc/pki/CA/app.csr -out /etc/pki/CA/certs/app.crt -days 365
#將生成的證書傳遞給申請者
[root@centos6 CA]$scp /etc/pki/CA/certs/app.crt 172.18.253.58:/etc/pki/CA/certs/
這樣,正常的證書頒發流程就算是完成了。將我們生成的根證書,子CA證書以及普通使用者證書匯出到Windows系統中,並安裝,然後我們就可以看到,整個證書路徑了。如下圖所示。
檢視證書狀態
檢視證書狀態,使用下面這條命令 ,可以檢視證書的內容以及頒發者的多種資訊。
openssl x509 -in /etc/pki/CA/cacert.pem -noout -text|issuer|subject|serial|dates
-text 證書的內容
-issuer 證書頒發者的資訊
-subject 證書主體的資訊
-serial 證書的序列號資訊
-dates 檢視證書的時間
# 證書頒發者的資訊
[root@localhost ~]#openssl x509 -in /etc/pki/CA/cacert.pem -noout -issuer
issuer= /C=CN/ST=shandong/L=qingdao/O=pojun.tech/OU=opt/CN=ca.pojun.tech
#
[root@localhost ~]#openssl x509 -in /etc/pki/CA/cacert.pem -noout -subject
subject= /C=CN/ST=shandong/L=qingdao/O=pojun.tech/OU=opt/CN=ca.pojun.tech
# 證書的有效時間
[root@localhost ~]#openssl x509 -in /etc/pki/CA/cacert.pem -noout -dates
notBefore=Sep 11 13:43:42 2017 GMT
notAfter=Sep 6 13:43:42 2037 GMT
#也可以根據index.txt 檔案中的證書編號,進行檢視狀態
[root@localhost ~]#openssl ca -status 01
Using configuration from /etc/pki/tls/openssl.cnf
01=Valid (V)
吊銷證書
這裡我們將子CA的證書吊銷掉。
A 首先在子CA主機上獲取到要吊銷的證書的serial
前面的例子中,我們的子CA證書的存放路徑是
/etc/pki/CA/certs/subca.crt
[root@centos6 CA]$openssl x509 -in /etc/pki/CA/certs/subca.crt -noout -serial -subject
serial=01
subject= /C=CN/ST=shandong/O=pojun.tech/OU=opt/CN=subca.pojun.tech
B 在根CA上根據客戶提交的serial與subject資訊,對比檢驗是否與index.txt檔案中的資訊一致,然後吊銷證書
#進入到CA的路徑下,檢視檔案目錄
[root@localhost CA]#pwd
/etc/pki/CA
[root@localhost CA]#tree
.
├── cacert.pem
├── certs
│ └── subca.crt # 這是直接頒發給子CA的證書檔案
├── crl
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│ └── 01.pem #這個就是與子CA證書一致的Serial檔案
├── private
│ └── cakey.pem
├── serial
├── serial.old
└── subca.csr
# 吊銷子CA的證書 使用revoke 命令
[root@localhost CA]#openssl ca -revoke /etc/pki/CA/newcerts/01.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Revoking Certificate 01.
Data Base Updated
C 指定第一個吊銷證書的編號
指定吊銷證書的編號,只有在更新證書吊銷列表之前,才需要操作
# 這條命令與生成證書時指定證書serial 號碼的作用是一致的。
# 就是說,指定下一個證書吊銷時的編號。
[root@localhost ~]#echo 01 > /etc/pki/CA/crlnumber
[root@localhost ~]#cat /etc/pki/CA/crlnumber
01
D 更新證書吊銷列表
前面指定了證書吊銷列表編號之後,就可以來更新證書吊銷列表了。
[root@localhost ~]#openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem: #這裡提示輸入密碼
檢視證書吊銷列表的檔案
[root@localhost ~]#openssl crl -in /etc/pki/CA/crl/crl.pem -noout -text
Certificate Revocation List (CRL): #證書吊銷列表
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /C=CN/ST=shandong/L=qingdao/O=pojun.tech/OU=opt/CN=ca.pojun.tech
Last Update: Sep 12 11:58:17 2017 GMT
Next Update: Oct 12 11:58:17 2017 GMT
CRL extensions:
X509v3 CRL Number:
1
Revoked Certificates: #這裡的標識顯示,證書已經被吊銷了
Serial Number: 01 #吊銷的序列號
Revocation Date: Sep 12 11:52:47 2017 GMT
Signature Algorithm: sha256WithRSAEncryption
b4:6e:f2:73:21:ed:c4:38:39:06:29:76:61:ac:d6:ee:a4:5d:
e8:cb:7c:8b:f8:01:21:ba:bd:b2:46:fa:ea:bf:de:fa:6e:f6:
85:d6:93:7c:81:b4:2d:d5:eb:c2:94:a3:6f:13:6d:f3:3f:48:
56:85:72:96:cf:e0:ea:a9:0e:07:43:6d:62:2d:4d:e2:2e:b5:
02:6a:27:7a:31:76:eb:4e:b1:d6:83:8b:d7:39:10:14:d6:94:
77:4b:10:d8:24:46:95:1b:48:87:16:77:ce:8c:1b:54:2c:4d:
ee:2f:24:13:10:62:30:32:74:9e:84:49:c9:dc:a9:fc:31:60:
57:b5:43:7a:a3:09:75:60:1e:6a:f2:26:e9:54:37:2d:ce:0b:
ac:b2:41:c2:d9:02:99:fc:a3:99:15:9c:10:a7:f4:be:08:83:
23:ee:ef:74:83:ea:fd:f7:c9:e1:87:6f:9b:1d:c3:df:88:2d:
79:2b:71:4b:9e:6f:ae:f9:08:d9:66:d4:f1:49:df:7e:89:99:
06:a3:86:72:37:02:78:0f:16:e8:87:8a:61:5b:a3:ac:e2:46:
38:ce:86:29:c9:c6:e5:8c:f8:25:2f:7e:d1:62:13:57:a3:a6:
10:42:13:b9:e4:0b:fa:9f:f4:d0:95:9b:5d:9b:2d:38:7f:8d:
ac:c0:e6:3f
在實際的使用過程中,有很多這樣的例項。例如我們經常使用的淘寶,在使用瀏覽器訪問淘寶的時候,就可以檢視淘寶的證書吊銷列表。如下圖所示。
至此,關於自己搭建CA的過程基本上就完成了。熟悉了上面的操作之後,就可以自己動手簡單的搭建一個證書了,然後也可以體驗一下整個流程