OpenSSL FAQ

火星人 @ 2014-03-12 , reply:0


  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).





[火星人 via ] OpenSSL FAQ已經有198次圍觀

http://www.coctec.com/docs/security/show-post-73030.html