在學習OpenSSL的過程中經常需要建立CA,再用此CA給用戶簽發證書,這個過程總是反覆進行,讓人不勝其煩,所以寫下了這個批處理把以上過程自動化。
把openssl.exe所在文件夾加入PATH環境變量,就可以在任何位置執行批處理(不建議安裝於C盤,因爲在生成文件的過程中可能會遇到的權限問題),本實驗OpenSSL版本號爲Windows版1.1.1c 28 May 2019。
有兩個命令可以用CA的身份給客戶簽發證書:CA命令和x509命令,將分爲兩篇文檔分別介紹;對於每個命令又細分爲CA根證書籤發和證書鏈簽發兩個部分,都給出了執行代碼,可以將其複製,然後粘貼到Windows命令行窗口執行(倒數第一行代碼的最後要有回車),或者也可保存爲批處理。
使用x509命令簽發證書的博文見這裏。
批處理會在D盤根目錄創建rca、ca1、ca2、ca3、host1、host2這幾個目錄,爲了保證乾淨的實驗環境,每次執行批處理都會先刪除它們然後重建,所以不要在這些目錄裏保存重要資料。切記!
實驗準備:用ca命令簽署證書會用到配置文件,默認是C:\Program Files\Common Files\SSL\openssl.cnf(可以通過環境變量 openssl_conf來指定),該文件有三個“節”(section,由中括號圈定)需要特別注意。
第一個節是[ CA_default ],定義了ca命令所需要的目錄結構及幾個固定的文件名,文件名包括CA的證書、CA的私鑰、數據庫文件、序列號文件:
[ CA_default ]
dir = ./demoCA # 頂層目錄,保存一切的起點
database = $dir/index.txt # 索引數據庫文件名及所在目錄
new_certs_dir = $dir/newcerts # 存放新證書的目錄
ertificate = $dir/cacert.pem # CA證書文件名及所在目錄
private_key = $dir/private/cakey.pem # CA私鑰文件名及所在目錄
serial = $dir/serial # 已簽發證書的序列號(16進制)所在目錄
如果你的取值與上文不同請修改,因爲批處理的代碼是按照這些取值設計的,#後面是中文註釋,可以不填入配置文件。
第二個節與“策略”有關,因爲policy= policy_match,所以找默認策略 [ policy_match ]:
[ policy_match ]
countryName = match # 國家
stateOrProvinceName = match # 省
organizationName = match # 組織名稱
organizationalUnitName = optional #組織單位名稱
commonName = supplied # FQDN
emailAddress = optional #電子郵件
這裏是DN字段,前三個字段的取值爲match,意思是請求文件的該字段取值,必須與簽署時輸入的CA證書的對應字段取值一模一樣,否則不能簽署。而這肯定會給CA簽署證書帶來麻煩,對此有三種解決方法:
1.把前三個字段的取值改爲optional(optional:可選項,可以留空;supplied :必選項,可以與CA對應字段的值不同)
2.重新聲明默認策略 policy= policy_anything 從而指向 [ policy_anything ]節,該節的DN字段沒有match值
3.CA命令使用選項:-policy policy_anything
本文采用第一種方法,即修改[ policy_match ],修改後的字段取值如下:
[ policy_match ]
countryName = optional # 國家
stateOrProvinceName = optional # 省
organizationName = optional # 組織名稱
organizationalUnitName = optional #組織單位名稱
commonName = supplied # FQDN
emailAddress = optional #電子郵件
第三個節是 [ v3_ca ],必須存在CA:true
[ v3_ca ]
basicConstraints = critical,CA:true
經過以上準備就可以創建CA並給其它用戶簽發證書了
根CA簽發:建立根CA,再由根CA直接籤發主機HOST1和HOST2的證書
批處理會在D盤根目錄下建立三個目錄:RCA,HOST1和HOST2,目錄結構如下:
cacert.pem是CA的根證書,index.txt是數據庫,記錄了曾經簽署和吊銷過的證書的歷史記錄;serial是爲下一個證書準備的序列號文件(本例初始序列號置爲01),每次簽署之後該序列號都會加一;cakey.pem是CA的私鑰,輸出的新證書在private裏留有備份,其主文件名是序列號。
此外,RCA目錄下還有CA的根證書、私鑰、公鑰,以及給用戶簽發的所有證書的備份。
HOST1/HOST2目錄分別存放了六個文件:HOST1/HOST2的證書、私鑰、公鑰,請求文件,以及CA根證書和CA的公鑰。
根CA:RCA
echo 刪除之前所有的文件 d:&cd\&rd/s/q host1&rd/s/q host2&rd/s/q rca&md host1&md host2&md rca&cd rca&md democa&md democa\newcerts&md democa\private echo 生成自簽名的根證書,私鑰和公鑰: openssl req -x509 -newkey rsa:8192 -keyout rca.key -out rca.cer -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=RCA/[email protected] -passout pass:abcd openssl rsa -in rca.key -pubout -out rca.pub -passin pass:abcd echo 把RCA的證書和公鑰拷貝到HOST1和HOST2 copy rca.cer d:\host1© rca.pub d:\host1© rca.cer d:\host2© rca.pub d:\host2 echo 把rca的證書和私鑰拷貝到配置文件要求的目錄,並建立數據庫文件和序列號文件,以便給用戶簽發證書 copy rca.cer democa\cacert.pem© rca.key democa\private\cakey.pem&cd.>democa\index.txt&echo 01>democa\serial echo 生成HOST1與HOST2的證書請求和私鑰 openssl req -newkey rsa:8192 -keyout host1.key -out host1.csr -subj /C=CN/ST=guangdong/L=shenzhen/O=SUN/OU=SUN-A/CN=host1 -passout pass:abcd openssl req -newkey rsa:8192 -keyout host2.key -out host2.csr -subj /C=CN/O=Tiger/ST=jiangsu/CN=host2 -passout pass:abcd echo 用RCA的私鑰簽署用戶請求 openssl ca -batch -notext -in host1.csr -out host1.cer -passin pass:abcd openssl ca -batch -notext -in host2.csr -out host2.cer -passin pass:abcd openssl rsa -in host1.key -pubout -out host1.pub -passin pass:abcd openssl rsa -in host2.key -pubout -out host2.pub -passin pass:abcd copy host1.* d:\host1© host2.* d:\host2 echo 驗證證書鏈 openssl verify -CAfile rca.cer -show_chain host1.cer openssl x509 -in rca.cer -noout -text|find "CA:TRUE" openssl x509 -in host1.cer -noout -text|find "CA:TRUE" openssl x509 -in host2.cer -noout -text|find "CA:TRUE"
證書鏈簽發:二級CA簽發證書
根CA:CA1
中間CA:CA2
CA1簽發CA2的證書,CA2簽發主機HOST1和HOST2的證書。
批處理在D盤根目錄下建立目錄CA1、CA2、HOST1、HOST2,各目錄存放的文件顧名思義,其中CA2保留所簽發的所有證書的備份。
echo 刪除之前所有的文件 d:&cd\&rd/s/q host1&rd/s/q host2&rd/s/q ca1&rd/s/q ca2&md host1&md host2&md ca1&md ca2&cd ca1&md democa&md democa\newcerts&md democa\private&cd\ca2&md democa&md democa\newcerts&md democa\private&cd\ca1 echo 生成自簽名的CA1根證書,私鑰和公鑰: openssl req -x509 -newkey rsa:8192 -keyout ca1.key -out ca1.cer -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=CA1/[email protected] -set_serial 0xca01 -passout pass:abcd openssl rsa -in ca1.key -pubout -out ca1.pub -passin pass:abcd echo 把CA1的證書和公鑰拷貝到HOST1和HOST2 copy ca1.cer d:\host1© ca1.pub d:\host1© ca1.cer d:\host2© ca1.pub d:\host2 echo 把CA1的證書和私鑰拷貝到配置文件指定的目錄,並建立數據庫文件和序列號文件,以便給CA2簽發證書 copy ca1.cer democa\cacert.pem© ca1.key democa\private\cakey.pem&cd.>democa\index.txt&echo ca02>democa\serial echo 生成CA2的請求,私鑰和公鑰 openssl req -newkey rsa:8192 -keyout ca2.key -out ca2.csr -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=CA2/[email protected] -passout pass:abcd openssl rsa -in ca2.key -pubout -out ca2.pub -passin pass:abcd echo 用CA1的私鑰簽署CA2的請求 openssl ca -extensions v3_ca -batch -notext -in ca2.csr -out ca2.cer -passin pass:abcd echo 把CA2的證書和公鑰拷貝到HOST1和HOST2 copy ca2.cer d:\host1© ca2.pub d:\host1© ca2.cer d:\host2© ca2.pub d:\host2 echo 把屬於CA2的所有文件拷貝到CA2目錄,同時把CA2的證書和私鑰拷貝到配置文件指出的目錄,以便用CA2的私鑰給用戶簽發證書 copy ca2.* \ca2© ca2.cer \ca2\democa\cacert.pem© ca2.key \ca2\democa\private\cakey.pem&cd\ca2&cd.>democa\index.txt&echo 01>democa\serial© \ca1\ca1.cer© \ca1\ca1.pub echo 生成HOST1與HOST2的證書請求和私鑰 openssl req -newkey rsa:8192 -keyout host1.key -out host1.csr -subj /C=CN/ST=guangdong/L=shenzhen/O=SUN/OU=SUN-A/CN=host1 -passout pass:abcd openssl req -newkey rsa:8192 -keyout host2.key -out host2.csr -subj /C=CN/O=Tiger/ST=jiangsu/CN=host2 -passout pass:abcd echo 用CA2的私鑰簽發用戶證書: openssl ca -batch -notext -in host1.csr -out host1.cer -passin pass:abcd openssl ca -batch -notext -in host2.csr -out host2.cer -passin pass:abcd openssl rsa -in host1.key -pubout -out host1.pub -passin pass:abcd openssl rsa -in host2.key -pubout -out host2.pub -passin pass:abcd echo 把HOST1和HOST2的所有文件拷貝到對應目錄 copy host1.* d:\host1© host2.* d:\host2 echo 驗證證書鏈 copy ca2.cer+ca1.cer ca-chain.cer openssl verify -CAfile ca-chain.cer host1.cer openssl verify -CAfile ca-chain.cer host2.cer openssl x509 -in ca1.cer -noout -text|find "CA:TRUE" openssl x509 -in ca2.cer -noout -text|find "CA:TRUE" openssl x509 -in host1.cer -noout -text|find "CA:TRUE" openssl x509 -in host2.cer -noout -text|find "CA:TRUE"
證書鏈簽發:三級CA簽發證書
根CA:CA1
中間CA:CA2和CA3
CA1簽發CA2的證書,CA2簽發CA3的證書,CA3給HOST1和HOST2簽發證書。
批處理在D盤根目錄下建立目錄CA1、CA2、CA3、HOST1、HOST2,各目錄存放的文件顧名思義,其中CA3保留所簽發的所有證書的備份。
echo 刪除之前所有的文件 d:&cd\&rd/s/q host1&rd/s/q host2&rd/s/q ca1&rd/s/q ca2&rd/s/q ca3&md host1&md host2&md ca1&md ca2&md ca3&cd ca1&md democa&md democa\newcerts&md democa\private&cd\ca2&md democa&md democa\newcerts&md democa\private&cd \ca3&md democa&md democa\newcerts&md democa\private&cd\ca1 echo 生成自簽名的CA1根證書,私鑰和公鑰: openssl req -x509 -newkey rsa:8192 -keyout ca1.key -out ca1.cer -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=CA1/[email protected] -set_serial 0xca01 -passout pass:abcd openssl rsa -in ca1.key -pubout -out ca1.pub -passin pass:abcd echo 把CA1的證書和公鑰拷貝到HOST1和HOST2 copy ca1.cer d:\host1© ca1.pub d:\host1© ca1.cer d:\host2© ca1.pub d:\host2 echo 把CA1的證書和私鑰拷貝到配置文件指出的目錄,並建立數據庫文件和序列號文件,以便給用CA1的私鑰給CA2簽發證書 copy ca1.cer democa\cacert.pem© ca1.key democa\private\cakey.pem&cd.>democa\index.txt&echo ca02>democa\serial echo 生成CA2的請求,私鑰和公鑰 openssl req -newkey rsa:8192 -keyout ca2.key -out ca2.csr -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=CA2/[email protected] -passout pass:abcd openssl rsa -in ca2.key -pubout -out ca2.pub -passin pass:abcd echo 用CA1的私鑰簽署CA2的請求 openssl ca -extensions v3_ca -batch -notext -in ca2.csr -out ca2.cer -passin pass:abcd echo 把CA2的證書和公鑰拷貝到HOST1和HOST2 copy ca2.cer d:\host1© ca2.pub d:\host1© ca2.cer d:\host2© ca2.pub d:\host2 echo 把屬於CA2的所有文件拷貝到CA2目錄,同時把CA2的證書和私鑰拷貝到配置文件指出的目錄,以便用CA2的私鑰給CA3簽發證書 copy ca2.* \ca2© ca2.cer \ca2\democa\cacert.pem© ca2.key \ca2\democa\private\cakey.pem&cd\ca2&cd.>democa\index.txt&echo ca03>democa\serial© \ca1\ca1.cer© \ca1\ca1.pub echo 生成CA3的請求,私鑰和公鑰 openssl req -newkey rsa:8192 -keyout ca3.key -out ca3.csr -days 3650 -subj /C=CN/ST=jiangsu/L=nanjing/O=Tiger/OU=T-CA/CN=CA3/[email protected] -passout pass:abcd openssl rsa -in ca3.key -pubout -out ca3.pub -passin pass:abcd echo 用CA2的私鑰簽署CA3的請求 openssl ca -extensions v3_ca -batch -notext -in ca3.csr -out ca3.cer -passin pass:abcd echo 把CA3的證書和公鑰拷貝到HOST1和HOST2 copy ca3.cer d:\host1© ca3.pub d:\host1© ca3.cer d:\host2© ca3.pub d:\host2 echo 用把屬於CA3的所有文件拷貝到CA3,同時把CA3的證書和私鑰拷貝到配置文件指出的目錄,以便用CA3的私鑰給用戶簽發證書 copy ca3.* \ca3© ca3.cer \ca3\democa\cacert.pem© ca3.key \ca3\democa\private\cakey.pem&cd\ca3&cd.>democa\index.txt&echo 01>democa\serial© ca3.cer \ca1© ca3.pub \ca1© \ca1\ca1.cer© \ca1\ca1.pub© \ca2\ca2.cer© \ca2\ca2.pub echo 生成HOST1與HOST2的證書請求和私鑰 openssl req -newkey rsa:8192 -keyout host1.key -out host1.csr -subj /C=CN/ST=guangdong/L=shenzhen/O=SUN/OU=SUN-A/CN=host1 -passout pass:abcd openssl req -newkey rsa:8192 -keyout host2.key -out host2.csr -subj /C=CN/O=Tiger/ST=jiangsu/CN=host2 -passout pass:abcd echo 用CA3的私鑰簽署用戶的請求 openssl ca -batch -notext -in host1.csr -out host1.cer -passin pass:abcd openssl ca -batch -notext -in host2.csr -out host2.cer -passin pass:abcd openssl rsa -in host1.key -pubout -out host1.pub -passin pass:abcd openssl rsa -in host2.key -pubout -out host2.pub -passin pass:abcd copy host1.* d:\host1© host2.* d:\host2 copy ca3.cer+ca2.cer+ca1.cer ca-chain.cer openssl verify -CAfile ca-chain.cer host1.cer openssl verify -CAfile ca-chain.cer host2.cer openssl x509 -in ca1.cer -noout -text|find "CA:TRUE" openssl x509 -in ca2.cer -noout -text|find "CA:TRUE" openssl x509 -in ca3.cer -noout -text|find "CA:TRUE" openssl x509 -in host1.cer -noout -text|find "CA:TRUE" openssl x509 -in host2.cer -noout -text|find "CA:TRUE"