OpenSSL命令行實例(2023.8.11更新)
零、前言
0.1?肺腑之言
OpenSSL的使用需要有一定的密碼學(xué)基礎(chǔ),例如對稱密鑰、非對稱密鑰,加密解密的知識。此外,還要了解PKI(公鑰基礎(chǔ)設(shè)施)體系、ASN.1結(jié)構(gòu)格式、PKCS標(biāo)準(zhǔn)的知識。
否則直接去操作這些命令的話,很多參數(shù)與配置都是兩眼一抹黑,也無法理解其中的一些含義,甚至即便我提供了示例,拿去使用后也會出現(xiàn)一大堆的問題。
所以,請先學(xué)習(xí)基礎(chǔ),再來學(xué)習(xí)本工具的使用。
筆者本身有學(xué)過密碼學(xué)的理論基礎(chǔ),再加上工作的緣故有接觸到實際的一些應(yīng)用,以及一直有前輩的引導(dǎo),但是依舊在使用的過程中感覺到有諸多細(xì)節(jié)始終沒有探究明白,深感慚愧。不過踩坑的過程中也有不少筆記,同時感覺網(wǎng)上關(guān)于這些命令的示例還是有些欠缺,于是斗膽拋磚引玉,希望大佬們能夠不吝賜教!

0.2 安裝OpenSSL流程:
(官網(wǎng)沒有提供windows的安裝包,linux的倒是有。另外,還有一種安裝openssl的方式就是去github下載源碼,然后進(jìn)行編譯,因為比較麻煩,所以這里不討論)
(1)開源網(wǎng)站(slproweb.com/products/Win32OpenSSL.html)下載安裝軟件?->?
(2)點擊安裝OpenSSL.exe ->?
(3)安裝完,設(shè)置環(huán)境變量(PATH新增:安裝路徑\bin)->?
(4)結(jié)束
注意:不管是用何種方式安裝,推薦使用1.1.1版本,如果想要用最新的,也可以用3.0,但是因為3.0太新了,且與舊版本有很多不兼容...至于,1.0和0.98之類的,太舊了,不推薦使用。
注意:我下載的是這個安裝包

注意:設(shè)置環(huán)境變量是為了能夠在cmd中,隨便一個文件夾底下都能執(zhí)行openssl命令

使用的命令:openssl version

0.3 本文基于版本
本文編寫主要是基于OpenSSL 3.0.1
多數(shù)命令也有使用OpenSSL 1.1.1h進(jìn)行校驗核對
此外,版本差異注意點,文中也有幾處提及,請留意閱讀。

一、RSA密鑰
1、生成2048長度的RSA密鑰對(公鑰在私鑰里,所以只會有一個私鑰文件,生成非對稱密鑰對的示例都一樣)
openssl genrsa -out test.key 2048

2、生成RSA密鑰對(使用保護(hù)口令:123456保護(hù))
openssl genrsa -aes256 -passout pass:123456? -out protectedByPwd.key 2048

3、RSA查看私鑰信息(如果私鑰有被口令保護(hù)則會要求輸入口令)
openssl rsa -in?test.key -text

4、RSA由私鑰文件獲取公鑰文件
openssl rsa -in?prvTest.key -pubout -out pubTest.key

5、查看公鑰信息
openssl rsa -pubin -in pubTest.key -text

6、由pkcs1的RSA私鑰獲得無保護(hù)的PKCS8格式私鑰
openssl pkcs8 -topk8 -inform PEM -in?test.key -outform PEM -nocrypt -out pkcs8Test.key

從內(nèi)容上來說,實際上pkcs8就是比pkcs1多了一些內(nèi)容(轉(zhuǎn)成der格式去看,然后依據(jù)ASN.1格式去解析,就能看出來)
另外,pem格式其實去掉頭尾,只看中間部分的話,你會發(fā)現(xiàn),就是一個被base64編碼后的字符串,解碼后就是der格式的全部內(nèi)容。


7、由PKCS1的RSA私鑰獲得加密的PKCS8格式私鑰(會讓設(shè)置新的私鑰文件的保護(hù)口令)
openssl pkcs8 -topk8 -inform PEM -in?test.key -outform PEM -out pkcs8CryptTest.pem

8、由PKCS8的RSA私鑰獲得PKCS1格式私鑰
openssl?rsa?-in?pkcs8.key?-out?pkcs1.keyr

二、ECC密鑰
1、生成不加密的密鑰對(公鑰在私鑰里,所以只會有一個私鑰文件,下同)
openssl ecparam -genkey -name prime256v1 -out eckey1.key

2、由無加密保護(hù)的私鑰來生成加密的私鑰(會要求輸入口令來保護(hù))
openssl ec -in ecPrivateKey1.key -aes256 -out ecProtectedPrvKey1.key

3、查看私鑰信息
openssl ec -in eckey1.key -text


4、依據(jù)pkcs1的私鑰獲得加密的pkcs8的私鑰文件
openssl pkcs8 -in ecPrivateKey1.key -topk8 -outform PEM -out ecPkcs8PrivateKey1.key

5、依據(jù)pkcs1的私鑰獲得不加密的pkcs8的私鑰文件
openssl pkcs8 -in ecPrivateKey1.key -topk8 -outform PEM -out ecPkcs8PrivateKey1.key -nocrypt

6、依據(jù)私鑰獲得公鑰
openssl ec -in ecPrivateKey1.key -pubout -out ecPublicKey1.key

三、加解密與簽名
1、生成簽名文件
test_prv.key表示用來簽名的私鑰
test.sign表示輸出的簽名結(jié)果文件的文件名
test.txt表示等待被簽名的源文件
-sha256表示使用的摘要算法,可以換成-md5、-sha1等
openssl?dgst?-sign test_prv.key?-sha256?-out?test.sign?test.txt

2、公鑰驗簽
test_pub.key表示用來驗簽的公鑰
test.sign表示簽名結(jié)果文件
test.txt表示被簽名的源文件
-sha256表示當(dāng)初簽名時使用的摘要算法,可以換成-md5、-sha1等,必須與簽名時使用的一致
openssl?dgst?-sha256?-verify?test_pub.key?-signature?test.sign test.txt

四、證書請求
1、生成證書請求(私鑰有保護(hù)口令需要輸入保護(hù)口令,然后會讓輸入subject信息,另外可選擇是否要設(shè)置保護(hù)密碼(直接回車不填就是無保護(hù)密碼))
(交互式)
openssl req -new -key?test.key -out?test.csr
(直接提供subject)
openssl req?-new -key test.key -out test.csr -subj /C=cn/ST=FJ/L=FZ/O=ab/OU=cd/emailAddress=123@qq.com/CN=test


2、將pem格式的證書請求轉(zhuǎn)為der格式
openssl req -inform PEM -in test_pem.csr -outform DER -out?test_der.csr

3、將der格式的證書請求轉(zhuǎn)為pem格式
openssl req -inform DER?-in test_der.csr?-outform PEM?-out?test_pem.csr

4、查看證書請求的信息
openssl req? -in test.csr -noout -text


5、生成帶擴(kuò)展字段的證書請求
先復(fù)制出來一個openssl.cnf文件,打開openssl.conf這里的注釋

然后在openssl.cnf這里設(shè)置好你要設(shè)置的擴(kuò)展字段

調(diào)用命令行指定配置文件為剛剛修改的openssl.cnf文件,以及指定要使用的配置為req(其實openssl默認(rèn)就是使用剛剛我們改的req配置)
openssl req -new -key test.key -out test.csr -config openssl.cnf??-section req
注:“-section req” 實測在1.1.1版本里并不支持(1.1.1h測試過,官網(wǎng)文檔也沒有提及-section的命令),得在3.0版本才支持(出現(xiàn)該命令)。1.1.1版本下會報錯:
req: Unrecognized flag section
req:Use -help for summary.

結(jié)果如圖:


五、證書
1、頒發(fā)v1版本的自簽名證書(一般CA證書使用的是SHA256的,指的是這個“-sha256”)
openssl x509 -req -days 3650 -sha256 -in ca.csr -signkey ca.key -out ca.crt
(V1版本的證書無擴(kuò)展屬性,所以不會受到約束)
可能報錯:
Unable to load config info from /usr/local/ssl/openssl.cnf
解決:
需要創(chuàng)建一個新的環(huán)境變量:
名稱: OPENSSL_CONF
值: C:\Program Files\OpenSSL\openssl.cnf?(即指向openssl.cnf 文件,若在openssl的安裝目錄里沒看到該文件,需要去網(wǎng)絡(luò)下載,最好是去官網(wǎng))
關(guān)于頒發(fā)證書時設(shè)置有效期:
openssl只支持以天為單位設(shè)置證書有效期,暫時我是沒找到可以以更小的時間單位設(shè)置有效期的辦法。
如果實在要用openssl頒發(fā)一本馬上就要過期的證書(如一個小時后就過期),那只能是先手動設(shè)置系統(tǒng)時間,然后頒發(fā)證書(因為openssl設(shè)置時間的時候,會使用當(dāng)前系統(tǒng)時間作為起始時間)(注意頒發(fā)完證書后,要把系統(tǒng)時間恢復(fù)正常一下)

2、頒發(fā)V3版本的自簽名證書
openssl x509 -req -days 3650 -sha256 -extfile openssl.cnf -extensions v3_ca -in?test.csr -signkey test.key -out test.crt
(推薦是把openssl安裝后本就有的openssl.cnf復(fù)制一份出來,放到你生成證書的文件夾里,然后有修改的話也是修改這個復(fù)制出來的配置文件,生成V3證書的時候指定比較方便,同時也不影響其他的頒證配置)
(注意,默認(rèn)的配置文件會使得頒發(fā)出來的V3證書的基本約束都是:末端證書,這樣的證書拿去做CA Chain校驗肯定會是失敗的,因為末端證書是不允許頒發(fā)子證書的)

3、用CA證書及CA私鑰對CSR頒發(fā)V3版本子證書
openssl x509 -req -days 3650 -sha256? -extfile openssl.cnf -extensions usr_cert?-in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt
(-CAcreateserial:如果序列號文件(serial number file)沒有指定,則自動創(chuàng)建它)
(可以對同一個證書請求進(jìn)行生成多個不同的證書,主要是頒發(fā)者不一樣,或者給分配的用途不一樣)
注意:-extension的設(shè)置將影響最終的證書的擴(kuò)展字段的內(nèi)容,而這里的指定,不一定得是usr_cert,也可以是其他你覺得里面的配置可以適用于這本證書的openssl.cnf中的配置。最終的證書擴(kuò)展字段的信息將會是你在-extension指定的配置項的信息。
如usr_cert我是這樣配置的(別抄,我這是隨便寫的):
這樣生成的證書,keyUsage等之類的擴(kuò)展字段就會是這里所設(shè)置的值。
如果你的證書請求里,本身就帶有keyUsage之類的擴(kuò)展字段,又想保留到最終的子證書里,目前我沒有找到X509命令底下可以直接保留的方式,只能是通過查看CSR里的擴(kuò)展字段信息,然后復(fù)制到頒發(fā)證書時會用到的openssl.cnf配置文件中(例如就把這個usr_cert里的值改改),然后生成的證書的擴(kuò)展字段就會和你所期望的一樣了。
按我了解到的信息來看,似乎只有ca命令支持從csr中復(fù)制擴(kuò)展字段到證書中的操作。詳細(xì)可見我的另一篇文章:OpenSSL命令行:自建CA&操作CRL

4、頒發(fā)V3子CA
openssl x509 -req -days 3650 -sha256? -extfile openssl.cnf -extensions v3_ca -in subCA.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out subCA.crt
注:若是仔細(xì)觀察,你會發(fā)現(xiàn),這個寫法與頒發(fā)普通的末端證書,其實就一個使用的extension變化了而已。是的,就是把指定usr_cert變成v3_ca就行。如果沒有特殊需求,可以直接用openssl默認(rèn)的配置。如果有需要,例如要限制子CA能夠繼續(xù)下發(fā)證書的級數(shù),可以去對應(yīng)的模塊(v3_ca)修改定制。注意點和前面一樣。
注:使用頒發(fā)好的子CA來繼續(xù)頒發(fā)子證書,寫法與普通的CA無異,所以此處不再贅述。
可能報錯:
Error adding extensions from section v3_ca
246A0000:error:1100007B:X509 V3 routines:v2i_AUTHORITY_KEYID:unable to get issuer keyid:crypto\x509\v3_akid.c:177:
246A0000:error:11000080:X509 V3 routines:X509V3_EXT_nconf_int:error in extension:crypto\x509\v3_conf.c:48:section=v3_ca, name=authorityKeyIdentifier, value=keyid:always,issuer
原因:
父證書是V1證書,沒有KeyIdentifier(使用者密鑰標(biāo)識符),所以openssl要把父證書的KeyIdentifier復(fù)制到子證書里作為authorityKeyIdentifier(授權(quán)密鑰標(biāo)識符)失敗了。這時候,如果硬要繼續(xù)頒證,那么就要在使用的openssl.cnf里修改配置:


5、證書驗證
5.1 兩級證書時(驗證test.crt是否是ca.crt這本CA證書頒發(fā)的)(當(dāng)把兩個證書名寫成一樣時,就是校驗是否是自簽名證書)
openssl verify -CAfile ca.crt?test.crt


可能報錯:
error 10 at 1 depth lookup: certificate has expired
error test1.crt: verification failed
可能原因:
證書過期,如果根證書過期,則校驗結(jié)果也會是失敗
可能報錯:
unable to get local issuer certificate
可能會附帶說明(OpenSSL3.0):No store loader found. For standard store loaders you need at least one of the default or base providers available. Did you forget to load them? Info: Global default library context
可能原因:
①子證書的頒發(fā)者的subject信息順序和父證書Subject不完全一致(通過ASN1parse解析對比可發(fā)現(xiàn),目測來看,OpenSSL會強制要求Issuer Subject的信息要和父證書的Subject一致)(如果是java生成的證書出現(xiàn)該問題,則可以參考我在文章末尾提供的倉庫中查看解決方案)


②父證書不是自簽名證書
解決方法:TODO
5.2 多級證書時
首先,找到完整的CA鏈(就是從自簽名證書到要驗證的證書的上級證書這一系列證書)
將它們拼接到一個新的文件里(推薦使用Linux的cat命令,或者開個文本編輯器復(fù)制粘貼也行)

結(jié)果如圖(這樣我們就得到了一個"CA證書鏈文件"):

注:沒試過文件里證書順序是亂的情況(證書五六本,然后隨便放進(jìn)來),因為我尋思著這種情況沒必要出現(xiàn)。我實測了按順序排列,然后正著和逆著都沒問題。
接著,使用命令,用剛剛獲得的ca-chain.crt來校驗普通的葉子證書normal.crt:
openssl verify -CAfile ca-chain.crt normal.crt

注:如果不把完整證書鏈合并到一個文件里來驗證normal.crt的話,即直接使用normal.crt的頒發(fā)者subCA.crt來校驗,會驗證失敗。因為openssl要求進(jìn)行證書鏈校驗的時候,要校驗到最上面那一級的CA,即自簽名根證書。

C = CN, ST = FJ, L = FZ, O = SUB, OU = CA, CN = subCA, emailAddress = 2@qq.com
error 2 at 1 depth lookup: unable to get issuer certificate
error normal.crt: verification failed
48870000:error:16000069:STORE routines:ossl_store_get0_loader_int:unregistered scheme:crypto\store\store_register.c:237:scheme=file
48870000:error:80000002:system library:file_open:No such file or directory:providers\implementations\storemgmt\file_store.c:269:calling stat(C:\Program Files\Common Files\SSL/certs)
48870000:error:16000069:STORE routines:ossl_store_get0_loader_int:unregistered scheme:crypto\store\store_register.c:237:scheme=C
48870000:error:1608010C:STORE routines:inner_loader_fetch:unsupported:crypto\store\store_meth.c:357:No store loader found. For standard store loaders you need at least one of the default or base providers available. Did you forget to load them? Info: Global default library context, Scheme (C : 0), Properties (<null>)

6、從證書中提取公鑰(證書里只有公鑰,沒有私鑰)
openssl?x509?-in?test.crt?-pubkey??-noout?>?testPub.key

7、將pem格式的證書轉(zhuǎn)為der格式(der格式:用二進(jìn)制編碼,直接用文本編輯器打開來看會是亂碼)
openssl x509 -in?test.crt -inform PEM -out test.der -outform DER


8、查看證書信息
openssl x509 -in test.crt -noout -text

各個字段的解釋與規(guī)范(標(biāo)準(zhǔn)定義文檔鏈接):https://datatracker.ietf.org/doc/html/rfc5280
注意最后面的這個"X509v3 Authority Key Indentifier"(譯名:授權(quán)密鑰標(biāo)識),這個擴(kuò)展字段將記錄父證書(也就是這本證書的頒發(fā)者證書的serial number),這使得其父證書就唯一了。哪怕都是自簽名的父證書,只是不同時間生成的,也將在證書鏈校驗時失敗,因為serial number 不同。
(關(guān)于Serial Number:由CA維護(hù)的為它所發(fā)的每個證書分配的唯一的序列號,用來追蹤和撤銷證書。只要擁有簽發(fā)者信息和序列號,就可以唯一標(biāo)識一個證書,最大不能過20個字節(jié))
校驗失敗如這個示例:


9、獲取證書的有效期起始時間
openssl x509 -in test.crt -noout -startdate

注意:GMT表示的是格林威治時間(其實證書文件中記錄的就是一個時間戳),所以如果要拿這個時間來比較的話,要注意時區(qū)問題。

10、獲取證書的有效期結(jié)束時間
openssl x509 -in test.crt -noout -enddate

注意:?-startdate 和?-enddate可同時使用,以一次性獲得起始和結(jié)束時間
注意:GMT表示的是格林威治時間(其實證書文件中記錄的就是一個時間戳),所以如果要拿這個時間來比較的話,要注意時區(qū)問題。

11、同時獲取有效期時間
openssl x509 -in test.crt -noout -dates

注意:GMT表示的是格林威治時間(其實證書文件中記錄的就是一個時間戳),所以如果要拿這個時間來比較的話,要注意時區(qū)問題。

12、校驗證書是否過期
openssl?x509?-in?test.crt?-checkend?0
檢查證書是否在n秒后過期,如果n=0表示當(dāng)前是否過期



13、讓頒發(fā)的證書文件里附帶上證書內(nèi)容(局限于pem格式)
openssl?x509?-req?-days?3650?-sha256??-extfile?openssl.cnf?-extensions?usr_cert?-in?test.csr?-CA?ca.crt?-CAkey?ca.key?-CAcreateserial?-out?test.crt?-text
使用命令: -text

相比于普通的頒證(即證書內(nèi)容只有一段base64編碼內(nèi)容),這種方式頒發(fā)出來的證書,會多出來展示證書的信息放在開頭位置。這樣的證書,是完全合法的。對于openssl之類的工具,也都能照常解析(其實就是會自動忽略這些內(nèi)容)。如果你要用自實現(xiàn)的代碼解析這類證書,那么也要注意去忽略這些內(nèi)容,避免處理報錯。

14、獲取證書的序列號和subject
openssl?x509?-in?test.crt?-noout?-serial?-subject

實際上,還有其他的命令可以使用以打印出證書的更多信息。具體請去文章末尾提供的OpenSSL官網(wǎng)查看。

六、P12文件
1、生成含證書鏈的P12文件(設(shè)置保護(hù)口令為111111)
openssl pkcs12 -export -in test.crt -inkey test.key -chain -CAfile ca.crt -password pass:111111 -out?test.p12??
注意:
test.crt和test.key是對應(yīng)的,test.key是test.crt對應(yīng)的test.csr生成時使用的私鑰
test.crt得是由ca.crt簽發(fā)的證書
可能報錯1:
Error certificate has expired getting chain.
可能報錯2:
Error?unable to get? local issuer certificate getting chain.
可能原因:
生成子證書時的配置信息問題,擴(kuò)展字段沒有加上父證書的授權(quán)標(biāo)識符
上面兩個報錯如果不準(zhǔn)備重新生成證書,則可能解決辦法:
openssl.cnf可能要配置一下,?不要嚴(yán)格判斷。

可能報錯3:
Error getting chain: certificate has expired
原因:
證書已經(jīng)過期
若根證書過期,將使得證書鏈校驗失敗,于是無法生成帶證書鏈的P12文件。經(jīng)過查閱官方文檔,并未發(fā)現(xiàn)有指令或配置可以忽略這個校驗

2、生成含多級證書鏈的P12文件(設(shè)置保護(hù)口令為111111)
openssl pkcs12 -export -in normal.crt -inkey normal.key -chain -CAfile ca-chain.crt -password pass:111111 -out normal.p12
注意:這里的證書鏈文件,要用完整的證書鏈。具體制作請看5.5.2這里的內(nèi)容。

3、生成不含證書鏈的P12文件(設(shè)置保護(hù)口令為111111)
openssl pkcs12 -export -in test.crt -inkey test.key?-password pass:111111 -out?test.p12??
注:
相比于上一個操作,因為不含證書鏈的校驗,所以如果test.crt過期,則依舊可以生成p12文件,不會有報錯

4、獲取p12文件中的數(shù)據(jù)
4.1?獲取CA證書
openssl?pkcs12?-in?test.p12?-nokeys?-cacerts?-out?ca.crt
4.2?獲取子證書
openssl?pkcs12?-in?test.p12?-nokeys?-clcerts?-out?test.crt
4.3?獲取子證書對應(yīng)的私鑰
openssl?pkcs12?-in?test.p12?-nocerts?-nodes?-out?test_prv.key

5、查看p12文件內(nèi)容
openssl?pkcs12?–in?test.p12?-info

輸入命令后,如果P12文件生成的時候有設(shè)置保護(hù)口令,則會要求輸入口令才能查看內(nèi)容。
一開始只會展示證書信息,若要進(jìn)一步查看私鑰信息則需要再次輸入保護(hù)口令才行,如果私鑰有保護(hù)口令則需要輸入私鑰的保護(hù)口令。


6、關(guān)于p12生成時的加密設(shè)置,因為1.1.1 -> 3.0的版本大更新,所以和之前的有差異,這里用第4點解析p12的方式實測如下
openssl 1.1.1:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
OpenSSL 3.0:
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF?hmacWithSHA256
注:默認(rèn)加密算法是 AES-256-CBC,其中 PBKDF2 用于密鑰派生(源自openssl的開源倉庫中的描述)
(另外,因為3.0對安全性進(jìn)行了升級,所以新舊版本不兼容解析這兩種加密方式的p12,除非使用特殊手段,具體在下個小點有介紹)

7、用OpenSSL3.0及以上版本解析用舊版本openssl等情況下生成的p12文件報錯
舊版本指的是:3.0之前的版本
以下是用openssl3.0.1版本解析一個由java純軟生成的等同于opesssl1.*版本生成的p12文件:
重點是這個:RC2-40-CBC,相似的還有很多,可以去官網(wǎng)查看
頁面地址:https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
原因就是:一些算法已經(jīng)被認(rèn)為是不安全的,所以在新的版本里進(jìn)行了剔除
官網(wǎng)說明:
The OpenSSL legacy provider supplies OpenSSL implementations of algorithms that have been deemed legacy. Such algorithms have commonly fallen out of use, have been deemed insecure by the cryptography community, or something similar.
We can consider this the retirement home of cryptographic algorithms.
而官網(wǎng)提供的兼容方式是,使用-legacy命令,如果沒有配置路徑的話,就需要同時提供路徑。其實就是告訴你的openssl,要用舊的版本的方式來解析這個p12文件。
官網(wǎng)的頁面鏈接:https://www.openssl.org/docs/man3.0/man1/openssl-pkcs12.html
官網(wǎng)說明:
-legacy
Use legacy mode of operation and automatically load the legacy provider. If OpenSSL is not installed system-wide, it is necessary to also use, for example,?
-provider-path ./providers
?or to set the environment variable?OPENSSL_MODULES?to point to the directory where the providers can be found.In the legacy mode, the default algorithm for certificate encryption is RC2_CBC or 3DES_CBC depending on whether the RC2 cipher is enabled in the build. The default algorithm for private key encryption is 3DES_CBC. If the legacy option is not specified, then the legacy provider is not loaded and the default encryption algorithm for both certificates and private keys is AES_256_CBC with PBKDF2 for key derivation.
另外,有國外開發(fā)人員表示:

譯文:在成功生成可以由OpenSSL 3.0-alpha直接處理的PKCS#12文件(使用AES等而不是RC2)后,無法使用Java 8加載,因為算法太新了 。因此,對于 PKCS#12,存在向后和向前兼容性問題...
相關(guān)兼容問題在github上的討論鏈接:
https://github.com/openssl/openssl/issues/14790
我試著用官網(wǎng)/國外老哥給出的方案——即使用-legacy,但是出現(xiàn)了找不到legacy.dll的問題,系統(tǒng)中根本找不到這個文件,都無法指定路徑
這是報錯信息:
這是另外幾種寫法:
openssl pkcs12 -in test.p12 -info -legacy
openssl pkcs12 -provider default -provider legacy -in test.p12 -info
我試了好幾種寫法,但是結(jié)果都是一樣的報錯,暫時認(rèn)為是我沒有這個文件的緣故,有待后續(xù)去找找看哪里去獲取這個文件,然后指定路徑試試。。。。

七、ASN1解析
openssl asn1parse -in test.crt
openssl asn1parse -in test.key
openssl asn1parse -in?test.csr
其中標(biāo)紅的表示可以隨便替換成一個ASN1格式的文件



八、補充
1、OpenSSL地址
中文手冊地址(比較簡陋):
https://www.openssl.net.cn/column/32.html
官網(wǎng)地址(資源更全面):
https://www.openssl.org
各個版本的區(qū)別(主要是1.1.1到3.0的變動很大):
https://www.openssl.org/news/changelog.html

2、可以輕松獲取的各個官方證書

在谷歌瀏覽器里按照這個點擊路徑,從“1”進(jìn)入到設(shè)置頁面,從“2”到安全頁面,從“安全頁面”進(jìn)入到管理證書頁面,則你可以下載瀏覽器默認(rèn)配置好的一大堆十分正規(guī)的證書,用來學(xué)習(xí)。(其他瀏覽器應(yīng)該大同小異)

3、關(guān)于命令默認(rèn)的格式
命令默認(rèn)都是pem格式,如果要用der格式就得指定輸出格式
(當(dāng)然,你可以通過修改openssl.cnf這個配置文件來自定義這個默認(rèn)文件格式)

4、openssl.cnf
這個文件是十分關(guān)鍵的一個文件,里面包含了很多的默認(rèn)配置,可以自己依據(jù)需要來調(diào)整
關(guān)于該文件的詳細(xì)介紹可以參考文章(往下劃一點內(nèi)容就能看到):http://www.jinbuguo.com/linux/openssl_install.html
順便說一句:
沒事可以把配置文件里的這一行注釋掉(1.1.1在[usr cert]里,3.0沒看到)(JAVA文檔中的說明:Netscape 證書規(guī)范將擴(kuò)展名指定為 IA5String,表示在查看證書時可能向用戶顯示的注釋):

不然頒發(fā)的證書里會有這一個字段:


5、關(guān)于一些文件類型及后綴含義
建議參考文章:https://blog.csdn.net/yetugeng/article/details/100629159


6、OpenSSL讀取內(nèi)容時的問題
OpenSSL讀取csr、crt文件時,需要加上BEGIN CERTIFICATE之類的文件類型標(biāo)識開頭和結(jié)尾,然后base64格式的文件內(nèi)容一行應(yīng)該是64個字符 (除了begin、end這兩行)

7、他人文章指路
綜述證書體系及C/S交互配置:https://blog.csdn.net/lk2684753/article/details/100160856

8、windows環(huán)境中文亂碼(2022.6.6補充)
如果你在控制臺輸入中文,準(zhǔn)備生成帶中文的subject的證書。那么,你會看到這樣的證書文件(下方截圖就是我的實測內(nèi)容):


使用openssl解析證書內(nèi)容(其實源頭是csr本身存進(jìn)去就是亂碼了):

原因:?字段值默認(rèn)情況下將被解釋為 ASCII(源自官網(wǎng)文檔說明),而不是大家所熟知的utf-8等支持中文的字符集,因此中文輸入肯定會成亂碼。
國外友人也有類似問題:https://github.com/openssl/openssl/issues/17453
思路:使用命令 -utf8(此選項會導(dǎo)致字段值被解釋為 UTF8 字符串,默認(rèn)情況下,它們被解釋為 ASCII。這意味著字段值(無論是從終端提示還是從配置文件獲?。┒急仨毷怯行У?UTF8 字符串)。但是,沒這么簡單,這個命令似乎會要求輸入到程序的內(nèi)容是utf8編碼,而我們windows的控制臺默認(rèn)是GBK編碼。直接使用的話,會報錯(版本1.1.1和3.0.1都試過了):

解決方案:
將控制臺編碼改成UTF-8,然后再用 -utf8 命令
(如果你要用改注冊表的方式,那么請慎重,因為會導(dǎo)致控制臺頁面原本正常顯示的中文變成亂碼。不過,如果你記得改回來的話倒也沒什么。推薦是用 chcp 65001 命令,臨時把當(dāng)前控制臺頁面轉(zhuǎn)成utf-8)
(如果你想用git之類自帶openssl的命令行窗口,那么,你還是要調(diào)整編碼格式,因為實測windows下git默認(rèn)的也是gbk編碼)
?但是我實測還是不行,不知道是不是哪里弄錯了...(因為我實際情況下,可以用純軟的方式生成沒問題的帶中文字段的證書,且中文證書真的很少見,所以就不準(zhǔn)備細(xì)究了)


9、 OpenSSL 自建CA和CRL的使用

另外,如果你還希望用純軟的方式實現(xiàn)密碼學(xué)相關(guān)的操作
c/c++?的話就用OpenSSL官方庫里的的方法
java的話,一般是使用Security庫以及BC庫來實現(xiàn),我的github倉庫https://github.com/17lhf/happyTest中有我關(guān)于依據(jù)這兩個庫進(jìn)行密碼學(xué)相關(guān)操作的示例(cryptology文件夾)或者這是我的B站專欄,有簡單介紹JAVA密碼學(xué)示例大集合,歡迎閱覽。