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

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

在 Linux 下須要生成 pkcs12 文件,當即想到 OpenSSL。鍵入以下命令dom

~ # 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】調試選項。spa

準備下斷點,該在哪裏下呢?調試

因爲錯誤信息爲 unable to load certificates ,其中過程確定涉及到證書加載函數,因此應該是 load_cert(不要問我爲何知道,由於我熟悉^_^)。若是不熟悉,能夠在 Source Insight 中用 F7 調出【Browse Project Symbols】對話框,輸入猜想的關鍵字,好比 load/certificate 等,也能找到 load_cert 函數。code

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

   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

出錯的調用棧爲blog

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_biossl

自底向上逐個切換調用棧,查看是哪裏引起了問題,結果在 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 選項,看來仍是有改進的空間。

相關文章
相關標籤/搜索