OpenSSL 使用拾遺(一)---- 生成 pkcs12 文件


從本期開始,記錄一些在使用 OpenSSL 過程中碰到的問題及解決辦法

在 Linux 下需要生成 pkcs12 文件,立即想到 OpenSSL。鍵入如下命令

~ # openssl pkcs12 -export -inkey clientkey.pem -in client.crt -out client.p12
No certificate matches private key

~ # openssl version
OpenSSL 0.9.8j 07 Jan 2009

奇怪,明明 clientkey.pem 和 client.crt 是剛生成的配套文件,其中前者保存私鑰,后者則是用戶證書(包含公鑰),怎么會出錯?

於是切換到 Windows 平台再驗證一番,雖然版本不同,但仍然報錯,只不過顯示的錯誤信息不一樣

d:\>openssl pkcs12 -export -inkey clientkey.pem -in client.crt -out client.p12
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
Loading 'screen' into random state - done
unable to load certificates

d:\>openssl version
WARNING: can't open config file: /usr/local/ssl/openssl.cnf
OpenSSL 1.0.1f 6 Jan 2014

沒辦法,只得祭出調試器,到源碼內部看個究竟。既然在 Windows 平台,就用順手的 Visual Studio。打開(以前建立的)OpenSSL 解決方案(OpenSSL 版本號 1.0.1f),切換到 Debug 配置,確保該配置實際包含【-Zi】調試選項。

准備下斷點,該在哪里下呢?

由於錯誤信息為 unable to load certificates ,其中過程肯定涉及到證書加載函數,所以應該是 load_cert(不要問我為什么知道,因為我熟悉^_^)。如果不熟悉,可以在 Source Insight 中用 F7 調出【Browse Project Symbols】對話框,輸入猜測的關鍵字,比如 load/certificate 等,也能找到 load_cert 函數。

反正不論如何,找到了懷疑函數 load_cert。在 Visual Studio 中新建此函數的斷點,並在 IDE 中配置好命令參數和工作目錄。F5 啟動,果然命中,說明成功了一半。繼續跟蹤,最后得到出錯的位置如下(位於文件 crypto\pem\pem_lib.c 中)

   695
   696        buf[254]='\0';
   697        for (;;)
   698            {
   699            i=BIO_gets(bp,buf,254);
   700
   701            if (i <= 0)
   702                {
   703                PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
   704                goto err; // <-- 【在此處出錯,並跳出】
   705                }
   706

出錯的調用棧為

openssl.exe!main
openssl.exe!do_cmd
openssl.exe!pkcs12_main
openssl.exe!load_certs
openssl.exe!load_certs_crls
libeay32.dll!PEM_X509_INFO_read_bio
libeay32.dll!PEM_read_bio

自底向上逐個切換調用棧,查看是哪里引發了問題,結果在 pkcs12_main 函數(文件 apps\pkcs12.c)中,發現如下一處調用

   461
   462        /* Load in all certs in input file */
   463        if(!(options & NOCERTS))
   464            {
   465            certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
   466                                "certificates"); // <-- 【以 PEM 格式加載證書】
   467            if (!certs)
   468                goto export_end;
   469

原來證書要求以 PEM 格式加載,回過頭用文本編輯器打開 client.crt。果然,此文件是 DER 格式的。

名不副實,自然是要出問題的。

原因知道了,解決辦法也立即有了。使用如下命令將證書轉為 PEM 格式

d:\>openssl x509 -in client.crt -inform der -out client.pem

然后再執行一次 pkcs12 命令

d:\>openssl pkcs12 -export -inkey clientkey.pem -in client.pem -out client.p12

問題得到解決。

自然想到,難道 pkcs12 命令就不提供 -inform 的格式轉換選項?
運行命令【openssl pkcs12 ?】,可以看到確實沒有提供 -inform 選項,看來還是有改進的空間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM