[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 應用技術 > SSL > 正文
OpenSSL FAQ
http://www.linuxforum.net 何偉平 譯 (2001-04-21 17:39:33)
                            
OpenSSL  -  經常問到的問題
--------------------------------------

* 目前的 OpenSSL 的版本是什?
* 文檔在哪裡?
* 我怎樣和 OpenSSL 的開發人員聯系?
* 要使用 OpenSSL 我需要申請專利許可証嗎?
* OpenSSL 線程安全嗎?
* 為什我收到 "PRNG not seeded" 這樣的錯誤信息?
* 為什鏈接器抱怨說有未定義的符號?
* 我在哪裡能得到編譯好了的 OpenSSL 版本?
* 我在 Windows 下編譯了一個程序,可它崩潰了:為什?
* 怎樣使用ASN1的函數讀寫DER編碼的緩沖區?
* 我想使用  這樣的宏,但卻給我一個錯誤,為什?
* 我調用了 <某個函數> 但是卻失敗了,為什?
* 我的錯誤輸出只是一大堆數字,它們是什意思?
* 為什我收到什未知算法的錯誤信息?
* 怎創建証書或者認証請求?
* 我為什不能創建認証請求?
* 為什  會因為証書認証錯誤而失敗?
* 為什我與使用OpenSSL的服務器聯接的時候總是只能使用弱加密?
* 我怎樣才能創建DSA証書?
* 為什我不能和一台使用DSA証書的服務器建立SSL聯接?
* 我怎才能刪除一個私鑰上的口令保護?
* 為什OpenSSH 的 configure 腳本不能檢測到 OpenSSL?
* 為什 OpenSSL 測試帶著 "bc: command not found" 信息失敗?
* 為什 OpenSSL 測試帶著 "bc: 1 no implemented信息失敗?
* 為什 OpenSSL 在 Alpha True64 Unix 上編譯失敗?
* 為什 OpenSSL 帶著"ar: command not found" 這樣的錯誤信息編譯失敗?


* 目前的 OpenSSL 的版本是什?

目前的版本可以從獲得.OpenSSL 0.9.6 在
2000 年 9 月 24 日發布.

除了當前的穩定版本以外,你還可以獲取 OpenSSL 的每日開發快照,在
,或者你也可以通過匿名 CVS 訪問
獲取.


* 文檔在哪裡?

OpenSSL 是一個庫,它為類似安全 web 服務器這樣的應用提供加密功能.
請仔細閱讀你想用的應用的文檔.INSTALL 文件解釋了如何安裝這個庫的問題.

OpenSSL 包含一個可以用執行加密功能的命令行工具.在 openssl(1) 手冊頁
裡有描述.給開發人員使用的文檔正在寫.有幾個手冊頁已經可以用了;libcrypto
和 libssl 庫的概述在 crypto(3) 和 ssl(3)的手冊頁裡描述.

OpenSSL 手冊頁安裝在 /usr/local/ssl/man (或者你象 INSTALL 裡描述的那樣聲明
的另外一個目錄).另外,你可以在閱讀大多數
當前版本的文檔.

有關 libcrypto 裡面的部件的更多內容,你可以閱讀 Ariel Glenn 的關 SSLeay 0.9
的文檔,它是 OpenSSL 的前身,它的文檔在 



那些文檔中有許多仍然適用 OpenSSL.

在 doc/openssl.txt 裡有一些關証書擴展和 PKCS#12 的文檔.

最早的 SSLeay 的文檔放在 OpenSSL 的 doc/ssleay.txt 裡.如果其他的資源都
不能幫助你的話,那它也許有用,不過你一定要知道它反映的是過時的 SSLeay
0.6.6 的版本.


* 我怎樣和 OpenSSL 的開發人員聯系?

README 文件描述了如何向 OpenSSL 提交臭虫報告和補丁.OpenSSL 郵件列表
的信息可以在  獲得.


* 要使用 OpenSSL 我需要申請專利許可証嗎?

README 文件的專利(patent)段列出了你使用OpenSSL時可能要遵循的專利.
請咨詢一位律師獲取關版權的信息.OpenSSL 開發組不提供法律建議.

你可以配置你的 OpenSSL 不使用 RC5 和 IDEA.用下面的命令:
 ./config no-rc5 no-idea


* OpenSSL 線程安全嗎?

是(有一個局限:一次 SSL 聯接不能使用多線程進行並發).在 Windows 和許多
Unix 系統上,OpenSSL 自動使用標準庫的多線程版本.如果你的平台不是這些平台
之一,請參考 INSTALL 文件.

多線程應用必須給 OpenSSL 提供兩個回調函數.這些都在 thread(3) 手冊頁裡描述.


* 為什我收到 "PRNG not seeded" 這樣的錯誤信息?


加密軟件需要一個非周期的數據源才能正確運轉.
許多開放源碼的操作系統提供一個"隨機設備"為這個用途服務.而在其他系統上,
應用在生成密鑰或者執行公鑰加密之前必須用合適的數據調用 RAND_add()或 
RAND_seed()函數.

有些有缺陷的應用不做這件事.到版本 0.9.5,OpenSSL 裡面的需要隨機數
的函數如果在隨機數發生器沒有收到一個128位的隨機值就會報一個錯誤.
如果出現這個錯誤,請與你使用的應用的作者聯系.很可能是他/她就沒有正確
使用這些東西.OpenSSL 0.9.5 和以的版本會拒絕執行那些有潛在的不安全加密
的動作,以此把錯誤顯示出來.

在沒有 /dev/urandom 的系統上,使用熵收集守護(Entropy Gathering Demon)
也是一個好計策);參閱 RAND_egd() 的手冊頁獲取細節.

大多數 openssl 的命令行工具會試圖使用文件 $HOME/.rnd (或者 $RANDFILE,
--如果設置了這個環境變量)用做產生 PRNG 種子.如果這個文件不存在或者太短,
就有可能出現那個 "PRNG not seeded" 錯誤信息.

[ OpenSSL 0.9.5 的用戶注意了:版本0.9.5的命令"openssl rsa"
並不做這件事,並且在那些沒有 /dev/urandom 的系統上用口令加密一個
RSA密鑰時會失效!這是一個庫裡面的臭虫;請使用更高版本的軟件.]

對 Solaris 2.6 而言,Tim Nibbe  和另外一些人建議
安裝 SUNski 包.該包來自 Sun 補丁 105710-01 (Sparc),它會增加一個
/dev/random 設備並確保其投入使用,通常是通過 $RANDFILE.其他 Solaris
版本也可能有類似補丁.不過,我們必須警告你 /dev/random 通常是一個塊設備,
這一點可能對 OpenSSL 有些影響.


* 為什鏈接器抱怨說有未定義的符號?


可能是因為編譯中斷了,而且 make 沒有認識到還缺少某些東西.運行
"make clean; make".

如果你用的是 ./Configure 而不是 ./config,請確信你選用了正確的目標機器.

在不同的 OS 版本之間的文件格式可能有些許區別(比如 sparcv8/sparcv9,
或者 a.out/elf).

如果你看到的錯誤信息包含下面的符號,請使用 "no-asm" 配置選項,
就象 INSTALL 裡描述的那樣:

 BF_cbc_encrypt, BF_decrypt, BF_encrypt, CAST_cbc_encrypt,
 CAST_decrypt, CAST_encrypt, RC4, RC5_32_cbc_encrypt, RC5_32_decrypt,
 RC5_32_encrypt, bn_add_words, bn_div_words, bn_mul_add_words,
 bn_mul_comba4, bn_mul_comba8, bn_mul_words, bn_sqr_comba4,
 bn_sqr_comba8, bn_sqr_words, bn_sub_words, des_decrypt3,
 des_ede3_cbc_encrypt, des_encrypt, des_encrypt2, des_encrypt3,
 des_ncbc_encrypt, md5_block_asm_host_order, sha1_block_asm_data_order

如果這些東西都不能幫你解決問題,那你可以試試當前的快照(源程序).
如果問題依舊,請提交一個錯誤報告.


* 我在哪裡能得到編譯好了的 OpenSSL 版本?

有些使用 OpenSSL 的應用是以二進制的形式發布的.當使用這樣的應用時,
你不需要自己安裝 OpenSSL;該應用會包含所需要的部分(比如,DLL)

如果你想在 Windows 系統上安裝 OpenSSL,但是你沒有 C 編譯器,請閱讀
INSTALL.W32 裡的 "mingw32" 節,獲取如何獲取和安裝自由的 GNU C 編譯器的信息.

許多 Linux 和 *BSD 發布版帶有 OpenSSL.


* 我在 Windows 下編譯了一個程序,可它崩潰了:為什?

通常是因為你忽略了 INSTALL.W32 裡的注解.你必須和多線程版本的 VC++ 運行時間
DLL 庫鏈接,否則沖突會導致程序崩潰:通常是在第一次 BIO 相關的讀寫操作的時候.


* 怎樣使用ASN1的函數讀寫DER編碼的緩沖區?

你有兩個選擇.一個是用一個內存BIO和 i2d_XXX_bio()或 d2i_XX_bio()一起使用,
另一個是你可以直接使用 i2d_XXX(),d2i_XXX() 函數.
因為這個問題是最常見的導致痛苦的問題,所以我們在這裡包含了一個使用PKCS7
的代碼片段做例子:(靠,我花了整整一周讀程序才找到方法,眼前一黑...)

unsigned char *buf, *p;
int len;

len = i2d_PKCS7(p7, NULL);
buf = OPENSSL_malloc(len); /* or Malloc, error checking omitted */
p = buf;
i2d_PKCS7(p7, &p);

到這裡的時候,buf 包含 len 字節的 p7的DER編碼.

反過來,假設我們在 buf 裡已經有 len 字節的數據:

unsigned char *p;
p = buf;
p7 = d2i_PKCS7(NULL, &p, len);

這個時候 p7 包含一個有效的 PKCS7 結構,如果發生錯誤則是一個 NULL.
如果有錯誤發生, ERR_print_errors(bio) 應該能給出更多信息.

使用臨時變量 'p' 是因為 ASN1 函數把傳入的指針增一,這樣它就做好
讀寫下一個結構的準備了.這樣常常會導致問題:如果不用臨時變量,
那緩沖區指針就會剛好指向正在被讀寫的數據的面.而那個地方很可能是
未初始化的數據,而且如果試圖釋放該緩沖區就有可能會導致不可預料的果,
因為它不再指向同一個地址.?


* 我想使用  這樣的宏,但卻給我一個錯誤,為什?

通常在你用一個C++編譯器編譯某些使用PKCS#12宏的東西的時候會出現這個現象.
在程序裡幾乎沒有使用PKCS#12的機會,分析和創建PKCS#12文件的更簡單的方法是
使用在 doc/openssl.txt 裡有文檔的 PKCS12_parse() 和 PKCS12_create()函數,
在 demos/pkcs12 裡有例子.'pkcs12' 應用程序必須使用該宏是因為它打印出
調試信息.


* 我調用了 <某個函數> 但是卻失敗了,為什?


在提交一個報告或者在郵件列表裡詢問某人之前,你應該試著先判斷原因.
尤其是你應該在失敗調用調用ERR_print_errors() 或者 ERR_print_errors_fp() 
然看看該信息是否有助你解決問題.不過要注意的是問題發生的地方可能比你
認為的地方
要早--如果可能地話,你應該在每個調用面檢查錯誤,否則實際的問題可能會
被隱藏起來,因為有些 OpenSSL 函數會清理錯誤狀態.


* 我的錯誤輸出只是一大堆數字,它們是什意思?

實際的格式在 ERR_print_errors() 手冊頁裡描述.
你應該先調用函數 ERR_load_crypto_strings() ,這樣信息就會以文本形式輸出.
如果你做不到這一點(比如那是預先編譯好了的二進制),你可以直接在錯誤
碼(第二個冒號面的十六進制數)上使用 errstr 工具.


* 為什我收到什未知算法的錯誤信息?


在好幾種情況下都有可能發生這樣的問題,比如讀取一個加密了的私鑰文件
或者試圖解密一個 PKCS#12 文件等.原因是忘了用OpenSSL_add_all_algorithms()
裝載OpenSSL 的算法表.參閱手冊頁獲取更多信息.


* 怎創建証書或者認証請求?

看看CA.pl(1)的手冊頁.它是一個封裝了'req','verify','ca'和'pkcs12'工具的
簡單容器.想要獲得更好的控制,請檢查相應的獨立工具的手冊頁以及証書擴展
文檔(目前在 doc/openssl.txt).


* 我為什不能創建認証請求?

通常你看到的錯誤是:

        unable to find 'distinguished_name' in config
        problems making Certificate Request

這是因為程序找不到配置文件.請察看 req(1) 的 DIAGNOSTICS 節獲取更多信息.


* 為什  會因為証書認証錯誤而失敗?

這個問題通常是由日志信息標識出來的,日志會象
"unable to get local issuer certificate" 或者 "self signed certificate" 這樣.
當我們驗証一個証書的時候,其根CA必須被OpenSSL"信任",通常這就意味著該CA的証書
必須放在一個目錄或者文件中,而且相關的程序還要配置成讀取它.
OpenSSL 的程序 'verify' 表現得類似這個性質,並且發出類似的錯誤信息:
請查閱 verify(1) 程序的手冊頁獲取更多信息.


* 為什我與使用OpenSSL的服務器聯接的時候總是只能使用弱加密?


幾乎肯定是因為你使用了老舊的"出口級"的瀏覽器,它們只支持弱加密.升級你的
瀏覽器以支持128位加密.


* 我怎樣才能創建DSA証書?

檢查 CA.pl(1) 的手冊頁獲取DSA証書的例子.


* 為什我不能和一台使用DSA証書的服務器建立SSL聯接?

通常你會看到一條信息說沒有共享的加密套件,而同樣的設置用RSA証書跑得很好.
有兩個可能原因.首先是客戶端可能不支持DSA服務器的聯接,大多數web瀏覽器
(包括 Netscape 和 MSIE)都只支持與使用RSA加密套件的服務器聯接.
另外一個原因是沒有給服務器提供一套DH參數.DH參數可以用 dhparam(1) 命令
創建然用 SSL_CTX_set_tmp_dh() 裝載,例子可以看:
app/s_server.c 裡的 s_server 的源程序.


* 我怎才能刪除一個私鑰上的口令保護?

首先你必須絕對確信你想這做.讓一個私鑰不加加密地存在是一個首要的安全
漏洞.如果你決定要這做,請查看 rsa(1) 和 dsa(1) 的手冊頁.


* 為什OpenSSH 的 configure 腳本不能檢測到 OpenSSL?

在 OpenSSH 1.2.2p1 裡有個毛病,就是 configure 腳本不能找到安裝的 OpenSSL 庫.
這個問題實際上是個小毛病,很容易修補,只要給 OpenSSH 發布打下面的一個補丁就行了:

----- snip:start -----
--- openssh-1.2.2p1/configure.in.orig   Thu Mar 23 18:56:58 2000
+++ openssh-1.2.2p1/configure.in        Thu Mar 23 18:55:05 2000
@@ -152,10 +152,10 @@
 AC_MSG_CHECKING([for OpenSSL/SSLeay directory])

 for ssldir in "" $tryssldir /usr /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do
        if test ! -z "$ssldir" ; then
-               LIBS="$saved_LIBS -L$ssldir"
+               LIBS="$saved_LIBS -L$ssldir/lib"
                CFLAGS="$CFLAGS -I$ssldir/include"
                if test "x$need_dash_r" = "x1" ; then
-                       LIBS="$LIBS -R$ssldir"
+                       LIBS="$LIBS -R$ssldir/lib"
                fi
        fi
        LIBS="$LIBS -lcrypto"
--- openssh-1.2.2p1/configure.orig      Thu Mar 23 18:55:02 2000
+++ openssh-1.2.2p1/configure   Thu Mar 23 18:57:08 2000
@@ -1890,10 +1890,10 @@
 echo "configure:1891: checking for OpenSSL/SSLeay directory" >&5
 for ssldir in "" $tryssldir /usr /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/pkg /opt /opt/openssl ; do
        if test ! -z "$ssldir" ; then
-               LIBS="$saved_LIBS -L$ssldir"
+               LIBS="$saved_LIBS -L$ssldir/lib"
                CFLAGS="$CFLAGS -I$ssldir/include"
                if test "x$need_dash_r" = "x1" ; then
-                       LIBS="$LIBS -R$ssldir"
+                       LIBS="$LIBS -R$ssldir/lib"
                fi

        fi
        LIBS="$LIBS -lcrypto"
----- snip:end -----


* 為什 OpenSSL 測試帶著 "bc: command not found" 信息失敗?

你沒安裝"bc",Unix 計算器.如果你想運行測試,從 ftp://ftp.gnu.org 
獲取GNU bc或從你的OS提供商那裡獲取.


* 為什 OpenSSL 測試帶著 "bc: 1 no implemented信息失敗?

在有些SCO的安裝或版本中的 bc 有些臭虫,會在運行測試套件(使用"make test")
的時候被觸發.返回的信息是"bc: 1 not implemented".對付這個問題的最好的方法
是找另外一個 bc 的實現然編譯/安裝之.比如,GNU bc(見
http://www.gnu.org/software/software.html 獲取下載指導)就可以很好地使用.


* 為什 OpenSSL 在 Alpha True64 Unix 上編譯失敗?

在一些運行True64 Unix 和 Compaq C 的 Alpha 安裝上,編譯 crypto/sha/sha_dgst.c 
會出錯,錯誤信息是'Fatal:  Insufficient virtual memory to continue compilation.'
從我們的測試看來,這個臭虫好象來自編譯器.現象是它使用了大量的駐留內存編譯某些
東西,很可能是一個表.問題很明顯地來自優化代碼,因為如果我們完全不進行優化(-O0)
那編譯就可以通過(並且編譯器只使用了大概 2MB 駐留內存,而不是 24MB 或者你的
當前極限).

有三個解決方法:

1. 把你當前數據段的大小的軟限制設得高一些.我們的經驗表明在AlphaServer DS10上大約 
241000 KB 就夠了.你可以用命令 'ulimit -Sd nnnnnn' 實現這些,這裡 'nnnnnn' 是
把限制值設置的 KB 數.

2. 如果你有一個比你需要的數量低的硬限制,而且你不能改變它,你可以用 -O0 
做為優化級別來編譯 OpenSSL.不過這樣做對那些希望從 OpenSSL 中獲取最大性能
的人來說不是特別好.更復雜一點兒的解決方法是否下面的方法:

----- snip:start -----
  make DIRS=crypto SDIRS=sha "`grep '^CFLAG=' Makefile.ssl | \
       sed -e 's/ -O[0-9] / -O0 /'`"
  rm `ls crypto/*.o crypto/sha/*.o | grep -v 'sha_dgst\.o'`
  make
----- snip:end -----

這樣將只用 -O0 編譯 sha_dgst.c,而其它的仍然用配置過程選取的優化級別.當完成
上面的工作,進行測試和安裝,最你就成了.


* 為什 OpenSSL 帶著"ar: command not found" 這樣的錯誤信息編譯失敗?

在 Solaris 2 上常見這個問題,因為 Sun 把 'ar' 和其它開發命令隱藏在一個
缺省時不在 $PATH 的目錄裡了.其中一個目錄是 '/usr/ccs/bin'.修補這個問題的
最快手段是按照下面的方法做(假設你使用的是 sh 或者任意 sh 兼容的 shell):

----- snip:start -----
  PATH=${PATH}:/usr/ccs/bin; export PATH
----- snip:end -----

然重新編譯.你實際上要做的是確保 '/usr/ccs/bin' 永久地存在你的 $PATH 裡,
比如通過你的 '.profile' 文件(同樣,假設你使用一個 sh 兼容的 shell).
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
 

★  樊強制作 歡迎分享  ★