原文:http://blog.sina.com.cn/s/blog_4d97eecf0100090n.html
文章寫的不錯 趕緊備份下 謝謝原作者
隨著計算機網(wǎng)絡(luò)技術(shù)的發(fā)展,方便快捷的互連網(wǎng)使人們漸漸習(xí)慣了從Web頁上收發(fā)E-mail、購物和
交易,這時Web頁面上需要傳輸重要或敏感的數(shù)據(jù),例如用戶的銀行帳戶、密碼等,所以網(wǎng)絡(luò)安全
就成為現(xiàn)代計算機網(wǎng)絡(luò)應(yīng)用急需解決的問題。
現(xiàn)行網(wǎng)上銀行和電子商務(wù)等大型的網(wǎng)上交易系統(tǒng)普遍采用HTTP和SSL相結(jié)合的方式。服務(wù)器端采用
支持SSL的Web服務(wù)器,用戶端采用支持SSL的瀏覽器實現(xiàn)安全通信。
SSL是Secure Socket Layer(安全套接層協(xié)議)的縮寫,可以在Internet上提供秘密性傳輸。
Netscape公司在推出第一個Web瀏覽器的同時,提出了SSL協(xié)議標(biāo)準(zhǔn),目前已有3.0版本。SSL采用公
開密鑰技術(shù)。其目標(biāo)是保證兩個應(yīng)用間通信的保密性和可靠性,可在服務(wù)器端和用戶端同時實現(xiàn)支
持。目前,利用公開密鑰技術(shù)的SSL協(xié)議,已成為Internet上保密通訊的工業(yè)標(biāo)準(zhǔn)。本文著重在
SSL協(xié)議和SSL程序設(shè)計兩方面談?wù)勛髡邔SL的理解。
SSL協(xié)議初步介紹
安全套接層協(xié)議能使用戶/服務(wù)器應(yīng)用之間的通信不被攻擊者,并且始終對服務(wù)器進(jìn)行認(rèn)證,
還可選擇對用戶進(jìn)行認(rèn)證。SSL協(xié)議要求建立在可靠的傳輸層協(xié)議(TCP)之上。SSL協(xié)議的優(yōu)勢在于
它是與應(yīng)用層協(xié)議獨立無關(guān)的,高層的應(yīng)用層協(xié)議(例如:HTTP,F(xiàn)TP,TELNET等)能透明地建立于
SSL協(xié)議之上。SSL協(xié)議在應(yīng)用層協(xié)議通信之前就已經(jīng)完成加密算法、通信密鑰的協(xié)商及服務(wù)器認(rèn)證
工作。在此之后應(yīng)用層協(xié)議所傳送的數(shù)據(jù)都會被加密,從而保證通信的私密性。
通過以上敘述,SSL協(xié)議提供的安全信道有以下三個特性:
1.數(shù)據(jù)的保密性
信息加密就是把明碼的輸入文件用加密算法轉(zhuǎn)換成加密的文件以實現(xiàn)數(shù)據(jù)的保密。加密的過程需要
用到密匙來加密數(shù)據(jù)然后再解密。沒有了密鑰,就無法解開加密的數(shù)據(jù)。數(shù)據(jù)加密之后,只有密匙
要用一個安全的方法傳送。加密過的數(shù)據(jù)可以公開地傳送。
2.數(shù)據(jù)的一致性
加密也能保證數(shù)據(jù)的一致性。例如:消息驗證碼(MAC),能夠校驗用戶提供的加密信息,接收者可
以用MAC來校驗加密數(shù)據(jù),保證數(shù)據(jù)在傳輸過程中沒有被篡改過。
3.安全驗證
加密的另外一個用途是用來作為個人的標(biāo)識,用戶的密匙可以作為他的安全驗證的標(biāo)識。
SSL是利用公開密鑰的加密技術(shù)(RSA)來作為用戶端與服務(wù)器端在傳送機密資料時的加密通訊協(xié)定。
目前,大部分的Web 服務(wù)器及瀏覽器都廣泛支持SSL 技術(shù)。當(dāng)瀏覽器試圖連接一個具有SSL認(rèn)證加
密的服務(wù)器時,就會喚醒一個SSL會話,瀏覽器檢查認(rèn)證,必須具備下面三個條件:
1)有一個權(quán)威機構(gòu)發(fā)放證書,當(dāng)然可以創(chuàng)建自我簽訂的證書(x509 結(jié)構(gòu))。
2)證書不能過期。
3)證書是屬于它所連接的服務(wù)器的。
只有全部具備了這三個條件,瀏覽器才能成功完成認(rèn)證。通過這三個條件,用戶能確認(rèn)其瀏覽器連接
到正確的服務(wù)器,而不是連接到一些想盜取用戶密碼等重要信息的虛假的服務(wù)器上。
在當(dāng)今的電子商務(wù)中還有一項被廣泛使用的安全協(xié)議是SET協(xié)議。SET(Secure Electronic Transaction,
安全電子交易)協(xié)議是由VISA和MasterCard兩大信用卡公司于1997年5月聯(lián)合推出的規(guī)范。SET能在電
子交易環(huán)節(jié)上提供更大的信任度、更完整的交易信息、更高的安全性和更少受欺詐的可能性。SET交
易分三個階段進(jìn)行:用戶向商家購物并確定支付;商家與銀行核實;銀行向商家支付貨款。每個階段都
涉及到RSA對數(shù)據(jù)加密,以及RSA數(shù)字簽名。使用SET協(xié)議,在一次交易中,要完成多次加密與解密操作,
故有很高的安全性,但SET協(xié)議比SSL協(xié)議復(fù)雜,商家和銀行都需要改造系統(tǒng)以實現(xiàn)互操作。
在Linux 下,比較流行支持SSL認(rèn)證的是OpenSSL服務(wù)器。OpenSSL項目是一個合作的項目,開發(fā)一個
健壯的、商業(yè)等級的、完整的開放源代碼的工具包,用強大的加密算法來實現(xiàn)安全的Socket層
(Secure Sockets Layer,SSL v2/v3)和傳輸層的安全性(Transport Layer Security,TLS v1)。
這個項目是由全世界的志愿者管理和開發(fā)OpenSSL工具包和相關(guān)文檔。
如何在Linux下配置OpenSSL服務(wù)器,首先從OpenSSL的主頁(http://www.openssl.org/)上下載
openssl-version.tar.gz軟件包來編譯安裝,與Apache服務(wù)器配合可以建立支持SSL的Web服務(wù)器,
并可以使用自我簽訂的證書做認(rèn)證,關(guān)于如何編譯、安裝OpenSSL服務(wù)器,可以參考一下OpenSSL HOWTO
文檔。
SSL 程序設(shè)計初步介紹
SSL 通訊模型為標(biāo)準(zhǔn)的C/S 結(jié)構(gòu),除了在 TCP 層之上進(jìn)行傳輸之外,與一般的通訊沒有什么明顯的區(qū)
別。在這里,我們主要介紹如何使用OpenSSL進(jìn)行安全通訊的程序設(shè)計。關(guān)于OpenSSL 的一些詳細(xì)的信
息請參考OpenSSL的官方主頁 http://www.openssl.org。
在使用OpenSSL前,必須先對OpenSSL 進(jìn)行初始化,以下的三個函數(shù)任選其一:
SSL_library_init(void);
OpenSSL_add_ssl_algorithms();
SSLeay_add_ssl_algorithms();
事實上 后面的兩個函數(shù)只是第一個函數(shù)的宏。
如果要使用OpenSSL的出錯信息,使用SSL_load_error_strings (void)進(jìn)行錯誤信息的初始化。以后
可以使用void ERR_print_errors_fp(FILE *fp) 打印SSL的錯誤信息。
一次SSL連接會話一般要先申請一個SSL 環(huán)境,基本的過程是:
1. SSL_METHOD* meth = TLSv1_client_method(); 創(chuàng)建本次會話連接所使用的協(xié)議,如果是客戶端可
以使用
SSL_METHOD* TLSv1_client_method(void); TLSv1.0 協(xié)議
SSL_METHOD* SSLv2_client_method(void); SSLv2 協(xié)議
SSL_METHOD* SSLv3_client_method(void); SSLv3 協(xié)議
SSL_METHOD* SSLv23_client_method(void); SSLv2/v3 協(xié)議
服務(wù)器同樣需要創(chuàng)建本次會話所使用的協(xié)議:
SSL_METHOD *TLSv1_server_method(void);
SSL_METHOD *SSLv2_server_method(void);
SSL_METHOD *SSLv3_server_method(void);
SSL_METHOD *SSLv23_server_method(void);
需要注意的是客戶端和服務(wù)器需要使用相同的協(xié)議。
2.申請SSL會話的環(huán)境 CTX,使用不同的協(xié)議進(jìn)行會話,其環(huán)境也是不同的。申請SSL會話環(huán)
境的OpenSSL函數(shù)是
SSLK_CTX* SSL_CTX_new (SSL_METHOD*); 參數(shù)就是前面我們申請的 SSL通訊方式。返回當(dāng)前
的SSL 連接環(huán)境的指針。
然后根據(jù)自己的需要設(shè)置CTX的屬性,典型的是設(shè)置SSL 握手階段證書的驗證方式和加載自己
的證書。
void SSL_CTX_set_verify (SSL_CTX* , int , int* (int, X509_STORE_CTX*) )
設(shè)置證書驗證的方式。
第一個參數(shù)是當(dāng)前的CTX 指針,第二個是驗證方式,如果是要驗證對方的話,就使用
SSL_VERIFY_PEER。不需要的話,使用SSL_VERIFY_NONE.一般情況下,客戶端需要驗證對方,而
服務(wù)器不需要。第三個參數(shù)是處理驗證的回調(diào)函數(shù),如果沒有特殊的需要,使用空指針就可以了。
void SSL_CTX_load_verify_locations(SSL_CTX*, const char* , const char*);
加載證書;
第一個參數(shù)同上,參數(shù)二是證書文件的名稱,參數(shù)三是證書文件的路徑;
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
加載本地的證書;type 指明證書文件的結(jié)構(gòu)類型;失敗返回-1
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
加載自己的私鑰;type 參數(shù)指明私鑰文件的結(jié)構(gòu)類型;失敗返回-1
加載了證書和文件之后,就可以驗證私鑰和證書是否相符:
BOOl SSL_CTX_check_private_key (SSL_CTX*);
3.既然SSL 使用TCP 協(xié)議,當(dāng)然需要把SSL attach 到已經(jīng)連接的套接字上了:
SSL* SSL_new (SSL_CTX*); 申請一個SSL 套節(jié)字;
int SSL_set_rfd (SSL*); 綁定只讀套接字
int SSL_set_wfd (SSL*); 綁定只寫套接字
int SSL_set_fd ( SSL*); 綁定讀寫套接字
綁定成功返回 1, 失敗返回0;
4. 接下來就是SSL 握手的動作了
int SSL_connect (SSL*); 失敗返回 -1
5. 握手成功之后,就可以進(jìn)行通訊了,使用SSL_read 和SS_write 讀寫SSL 套接字代替?zhèn)鹘y(tǒng)的
read 、write
int SSL_read (SSL *ssl, char *buf, int num );
int SSL_write (SSL *ssl, char *buf, int num);
如果是服務(wù)器,則使用 SSL_accept 代替?zhèn)鹘y(tǒng)的 accept 調(diào)用
int SSL_accept(SSL *ssl);
6. 通訊結(jié)束,需要釋放前面申請的 SSL資源
int SSL_shutdown(SSL *ssl); 關(guān)閉SSL套接字;
void SSL_free (ssl); 釋放SSL套接字;
void SSL_CTX_free (ctx); 釋放SSL環(huán)境;
OpenSSL 雖然已經(jīng)發(fā)展到了0.9.96版本,但是它的文檔還很少,甚至連最基本的man 函數(shù)手
冊都沒有完成。所以,本文緊緊是講述了使用OpenSSL 進(jìn)行程序設(shè)計的框架。更加詳細(xì)的資
料可以參考OpenSSL 的文檔或者 Apache mod_ssl 的文檔。
通過以上的介紹,我想讀者對SSL協(xié)議已經(jīng)有了一定的了解,作者有機會將會繼續(xù)給大家介紹
SSL協(xié)議的其他方面的內(nèi)容。
SSL原理解密
本文出自:
http://noc.cstnet.net.cn/
范曉明
RSA公鑰加密在計算機產(chǎn)業(yè)中被廣泛使用在認(rèn)證和加密。可以從RSA Data Security Inc.獲得的RSA公鑰加密許可證。公鑰加密是使用一對非對稱的密碼加密或解密的方法。每一對密碼由公鑰和私鑰組成。公鑰被廣泛發(fā)布。私鑰是隱密的,不 公開。用公鑰加密的數(shù)據(jù)只能夠被私鑰解密。反過來,使用私鑰加密的數(shù)據(jù)只能用公鑰解密。這個非對稱的特性使得公鑰加密很有用。
使用公鑰加密法認(rèn)證
認(rèn)證是一個身份認(rèn)證的過程。在下列例子中包括甲和乙,公鑰加密會非常輕松地校驗身份。符號{數(shù)據(jù)} key意味著"數(shù)據(jù)"已經(jīng)使用密碼加密或解密。假如甲想校驗乙的身份。乙有一對密碼,一個是公開的,另一個是私有的。乙透露給甲他的公鑰。甲產(chǎn)生一個隨機 信息發(fā)送給乙。甲——〉乙:random-message
乙使用他的私鑰加密消息,返回甲加密后的消息。 乙——〉甲:{random-message}乙的私鑰
甲收到這個消息然后使用乙的以前公開過的公鑰解密。他比較解密后的消息與他原先發(fā)給乙的消息。如果它們完全一致,就會知道在與乙說話。任意一個中間人不會知道乙的私鑰,也不能正確加密甲檢查的隨機消息。
除非你清楚知道你加密的消息。用私鑰加密消息,然后發(fā)送給其他人不是一個好主意。因為加密值可能被用來對付你,需要注意的是:因為只有你才有私鑰,所以只 有你才能加密消息。所以,代替加密甲發(fā)來的原始消息,乙創(chuàng)建了一個信息段并且加密。信息段取自隨機消息(random-message)并具有以下有用的 特性:
1. 這個信息段難以還原。任何人即使偽裝成乙,也不能從信息段中得到原始消息;
2. 假冒者將發(fā)現(xiàn)不同的消息計算出相同的信息段值;
3. 使用信息段,乙能夠保護(hù)自己。他計算甲發(fā)出的隨機信息段,并且加密結(jié)果,并發(fā)送加密信息段返回甲。甲能夠計算出相同的信息段并且解密乙的消息認(rèn)證乙。
這個技術(shù)僅僅描繪了數(shù)字簽名。通過加密甲產(chǎn)生的隨機消息,乙已經(jīng)在甲產(chǎn)生的消息簽名。因此我們的認(rèn)證協(xié)議還需要一次加密。一些消息由乙產(chǎn)生:
甲——〉乙:你好,你是乙么?
乙——〉甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
當(dāng)你使用這個協(xié)議,乙知道他發(fā)送給乙的消息,他不介意在上面簽名。他先發(fā)送不加密的信息,"甲,我是乙。",然后發(fā)送信息段加密的消息版本。甲可以非常方便地校驗乙就是乙,同時,乙還沒有在他不想要的信息上簽名。
提交公鑰
那么,乙怎樣以可信的方式提交他的公鑰呢?看看認(rèn)證協(xié)議如下所示:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的公鑰
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] } 乙的私鑰
在這個協(xié)議下,任何人都能夠成為"乙"。所有你所要的只是公鑰和私鑰。你發(fā)送給甲說你就是乙,這樣你的公鑰就代替了乙的密碼。然后,你發(fā)送用你的私鑰加密的消息,證明你的身份。甲卻不能發(fā)覺你并不是乙。為了解決這個問題,標(biāo)準(zhǔn)組織已經(jīng)發(fā)明了證書。一個證書有以下的內(nèi)容:
* 證書的發(fā)行者姓名
* 發(fā)行證書的組織
* 標(biāo)題的公鑰
* 郵戳
證書使用發(fā)行者的私鑰加密。每一個人都知道證書發(fā)行者的公鑰(這樣,每個證書的發(fā)行者擁有一個證書)。證書是一個把公鑰與姓名綁定的協(xié)議。通過使用證書技術(shù),每一個人都可以檢查乙的證書,判斷是否被假冒。假設(shè)乙控制好他的私鑰,并且他確實是得到證書的乙,就萬事大吉了。
這些是修訂后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲, 我是乙] } 乙的私鑰
現(xiàn)在當(dāng)甲收到乙的第一個消息,他能檢查證書,簽名(如上所述,使用信息段和公鑰解密),然后檢查標(biāo)題(乙的姓名),確定是乙。他就能相信公鑰就是乙的公鑰 和要求乙證明自己的身份。乙通過上面的過程,制作一個信息段,用一個簽名版本答復(fù)甲。甲可以校驗乙的信息段通過使用從證書上得到的公鑰并檢查結(jié)果。
如果一個黑客,叫H
甲——〉H:你好
H——〉不能建立一個令甲相信的從乙的消息。
交換密碼(secret)
一旦甲已經(jīng)驗證乙后,他可以發(fā)送給乙一個只有乙可以解密、閱讀的消息:
甲——〉乙:{secret}乙的公鑰
唯一找到密碼的方法只有使用乙的私鑰解碼上述的信息。交換密碼是另一個有效使用密碼加密的方法。即使在甲和乙之間的通訊被偵聽,只有乙才能得到密碼。
使用密碼作為另一個secret-key增強了網(wǎng)絡(luò)的安全性,但是這次這是一個對稱的加密算法(例如DES、RC4、IDE甲)。因為甲在發(fā)送給乙之前產(chǎn) 生了密碼,所以甲知道密碼。乙知道密碼因為乙有私鑰,能夠解密甲的信息。但他們都知道密碼,他們都能夠初始化一個對稱密碼算法,而且開始發(fā)送加密后的信 息。這兒是修定后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉乙:ok 乙,here is a secret {secret}乙的公鑰
乙——〉甲:{some message}secret-key
黑客
那么如果有一個惡意的黑客H在甲和乙中間,雖然不能發(fā)現(xiàn)甲和乙已經(jīng)交換的密碼,但能干擾他們的交談。他可以放過大部分信息,選擇破壞一定的信息(這是非常簡單的,因為他知道甲和乙通話采用的協(xié)議)。
甲——〉H:你好
H——〉乙:你好
乙——〉H:嗨,我是乙,乙的校驗
H——〉甲:嗨,我是乙,乙的校驗
甲——〉H:prove it
H——〉乙:prove it
乙——〉H:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
H——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉H:ok 乙,here is a secret {secret} 乙的公鑰
H——〉乙:ok 乙,here is a secret {secret} 乙的公鑰
乙——〉H:{some message}secret-key
H——〉甲:Garble[{some message}secret-key ]
H忽略一些數(shù)據(jù)不修改,直到甲和乙交換密碼。然后H干擾乙給甲的信息。在這一點上,甲相信乙,所以他可能相信已經(jīng)被干擾的消息并且盡力解密。
需要注意的是,H不知道密碼,他所能做的就是毀壞使用秘鑰加密后的數(shù)據(jù)。基于協(xié)議,H可能不能產(chǎn)生一個有效的消息。但下一次呢?
為了阻止這種破壞,甲和乙在他們的協(xié)議中產(chǎn)生一個校驗碼消息(message authentication code)。一個校驗碼消息(MAC)是一部分由密碼和一些傳輸消息產(chǎn)生的數(shù)據(jù)。信息段算法描述的上述特性正是它們抵御H的功能:
MAC= Digest[some message,secret ]
因為H不知道密碼,他不能得出正確的值。即使H隨機干擾消息,只要數(shù)據(jù)量大,他成功的機會微乎其微。例如,使用HD5(一個RSA發(fā)明的好的加密算法), 甲和乙能夠發(fā)送128位MAC值和他們的消息。H猜測正確的MAC的幾率將近1/18,446,744,073,709,551,616約等于零。
這是又一次修改后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:嗨,我是乙,乙的校驗
甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
ok 乙,here is a secret {secret} 乙的公鑰
{some message,MAC}secret-key
現(xiàn)在H已經(jīng)無技可施了。他干擾了得到的所有消息,但MAC計算機能夠發(fā)現(xiàn)他。甲和乙能夠發(fā)現(xiàn)偽造的MAC值并且停止交談。H不再能與乙通訊。
OpenSSL FAQ
http://www.linuxforum.net
何偉平 譯
OpenSSL - 經(jīng)常問到的問題
--------------------------------------
* 目前的 OpenSSL 的版本是什么?
* 文檔在哪里?
* 我怎樣和 OpenSSL 的開發(fā)人員聯(lián)系?
* 要使用 OpenSSL 我需要申請專利許可證嗎?
* OpenSSL 線程安全嗎?
* 為什么我收到 "PRNG not seeded" 這樣的錯誤信息?
* 為什么鏈接器抱怨說有未定義的符號?
* 我在哪里能得到編譯好了的 OpenSSL 版本?
* 我在 Windows 下編譯了一個程序,可它崩潰了:為什么?
* 怎樣使用ASN1的函數(shù)讀寫DER編碼的緩沖區(qū)?
* 我想使用 這樣的宏,但卻給我一個錯誤,為什么?
* 我調(diào)用了 <某個函數(shù)> 但是卻失敗了,為什么?
* 我的錯誤輸出只是一大堆數(shù)字,它們是什么意思?
* 為什么我收到什么未知算法的錯誤信息?
* 怎么創(chuàng)建證書或者認(rèn)證請求?
* 我為什么不能創(chuàng)建認(rèn)證請求?
* 為什么 會因為證書認(rèn)證錯誤而失敗?
* 為什么我與使用OpenSSL的服務(wù)器聯(lián)接的時候總是只能使用弱加密?
* 我怎樣才能創(chuàng)建DSA證書?
* 為什么我不能和一臺使用DSA證書的服務(wù)器建立SSL聯(lián)接?
* 我怎么才能刪除一個私鑰上的口令保護(hù)?
* 為什么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 日發(fā)布.
除了當(dāng)前的穩(wěn)定版本以外,你還可以獲取 OpenSSL 的每日開發(fā)快照,在
,或者你也可以通過匿名 CVS 訪問
獲取.
* 文檔在哪里?
OpenSSL 是一個庫,它為類似安全 web 服務(wù)器這樣的應(yīng)用提供加密功能.
請仔細(xì)閱讀你想用的應(yīng)用的文檔.INSTALL 文件解釋了如何安裝這個庫的問題.
OpenSSL 包含一個可以用于執(zhí)行加密功能的命令行工具.在 openssl(1) 手冊頁
里有描述.給開發(fā)人員使用的文檔正在寫.有幾個手冊頁已經(jīng)可以用了;libcrypto
和 libssl 庫的概述在 crypto(3) 和 ssl(3)的手冊頁里描述.
OpenSSL 手冊頁安裝在 /usr/local/ssl/man (或者你象 INSTALL 里描述的那樣聲明
的另外一個目錄).另外,你可以在閱讀大多數(shù)
當(dāng)前版本的文檔.
有關(guān) libcrypto 里面的部件的更多內(nèi)容,你可以閱讀 Ariel Glenn 的關(guān)于 SSLeay 0.9
的文檔,它是 OpenSSL 的前身,它的文檔在
那些文檔中有許多仍然適用于 OpenSSL.
在 doc/openssl.txt 里有一些關(guān)于證書擴展和 PKCS#12 的文檔.
最早的 SSLeay 的文檔放在 OpenSSL 的 doc/ssleay.txt 里.如果其他的資源都
不能幫助你的話,那么它也許有用,不過你一定要知道它反映的是過時的 SSLeay
0.6.6 的版本.
* 我怎樣和 OpenSSL 的開發(fā)人員聯(lián)系?
README 文件描述了如何向 OpenSSL 提交臭蟲報告和補丁.OpenSSL 郵件列表
的信息可以在 獲得.
* 要使用 OpenSSL 我需要申請專利許可證嗎?
README 文件的專利(patent)段列出了你使用OpenSSL時可能要遵循的專利.
請咨詢一位律師獲取關(guān)于版權(quán)的信息.OpenSSL 開發(fā)組不提供法律建議.
你可以配置你的 OpenSSL 不使用 RC5 和 IDEA.用下面的命令:
./config no-rc5 no-idea
* OpenSSL 線程安全嗎?
是(有一個局限:一次 SSL 聯(lián)接不能使用多線程進(jìn)行并發(fā)).在 Windows 和許多
Unix 系統(tǒng)上,OpenSSL 自動使用標(biāo)準(zhǔn)庫的多線程版本.如果你的平臺不是這些平臺
之一,請參考 INSTALL 文件.
多線程應(yīng)用必須給 OpenSSL 提供兩個回調(diào)函數(shù).這些都在 thread(3) 手冊頁里描述.
* 為什么我收到 "PRNG not seeded" 這樣的錯誤信息?
加密軟件需要一個非周期的數(shù)據(jù)源才能正確運轉(zhuǎn).
許多開放源碼的操作系統(tǒng)提供一個"隨機設(shè)備"為這個用途服務(wù).而在其他系統(tǒng)上,
應(yīng)用在生成密鑰或者執(zhí)行公鑰加密之前必須用合適的數(shù)據(jù)調(diào)用 RAND_add()或
RAND_seed()函數(shù).
有些有缺陷的應(yīng)用不做這件事.到版本 0.9.5,OpenSSL 里面的需要隨機數(shù)
的函數(shù)如果在隨機數(shù)發(fā)生器沒有收到一個128位的隨機值就會報一個錯誤.
如果出現(xiàn)這個錯誤,請與你使用的應(yīng)用的作者聯(lián)系.很可能是他/她就沒有正確
使用這些東西.OpenSSL 0.9.5 和以后的版本會拒絕執(zhí)行那些有潛在的不安全加密
的動作,以此把錯誤顯示出來.
在沒有 /dev/urandom 的系統(tǒng)上,使用熵收集守護(hù)(Entropy Gathering Demon)
也是一個好計策);參閱 RAND_egd() 的手冊頁獲取細(xì)節(jié).
大多數(shù) openssl 的命令行工具會試圖使用文件 $HOME/.rnd (或者 $RANDFILE,
--如果設(shè)置了這個環(huán)境變量)用做產(chǎn)生 PRNG 種子.如果這個文件不存在或者太短,
就有可能出現(xiàn)那個 "PRNG not seeded" 錯誤信息.
[ OpenSSL 0.9.5 的用戶注意了:版本0.9.5的命令"openssl rsa"
并不做這件事,并且在那些沒有 /dev/urandom 的系統(tǒng)上用口令加密一個
RSA密鑰時會失效!這是一個庫里面的臭蟲;請使用更高版本的軟件.]
對于 Solaris 2.6 而言,Tim Nibbe 和另外一些人建議
安裝 SUNski 包.該包來自 Sun 補丁 105710-01 (Sparc),它會增加一個
/dev/random 設(shè)備并確保其投入使用,通常是通過 $RANDFILE.其他 Solaris
版本也可能有類似補丁.不過,我們必須警告你 /dev/random 通常是一個塊設(shè)備,
這一點可能對 OpenSSL 有些影響.
* 為什么鏈接器抱怨說有未定義的符號?
可能是因為編譯中斷了,而且 make 沒有認(rèn)識到還缺少某些東西.運行
"make clean; make".
如果你用的是 ./Configure 而不是 ./config,請確信你選用了正確的目標(biāo)機器.
在不同的 OS 版本之間的文件格式可能有些許區(qū)別(比如 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
如果這些東西都不能幫你解決問題,那你可以試試當(dāng)前的快照(源程序).
如果問題依舊,請?zhí)峤灰粋€錯誤報告.
* 我在哪里能得到編譯好了的 OpenSSL 版本?
有些使用 OpenSSL 的應(yīng)用是以二進(jìn)制的形式發(fā)布的.當(dāng)使用這樣的應(yīng)用時,
你不需要自己安裝 OpenSSL;該應(yīng)用會包含所需要的部分(比如,DLL)
如果你想在 Windows 系統(tǒng)上安裝 OpenSSL,但是你沒有 C 編譯器,請閱讀
INSTALL.W32 里的 "mingw32" 節(jié),獲取如何獲取和安裝自由的 GNU C 編譯器的信息.
許多 Linux 和 *BSD 發(fā)布版帶有 OpenSSL.
* 我在 Windows 下編譯了一個程序,可它崩潰了:為什么?
通常是因為你忽略了 INSTALL.W32 里的注解.你必須和多線程版本的 VC++ 運行時間
DLL 庫鏈接,否則沖突會導(dǎo)致程序崩潰:通常是在第一次 BIO 相關(guān)的讀寫操作的時候.
* 怎樣使用ASN1的函數(shù)讀寫DER編碼的緩沖區(qū)?
你有兩個選擇.一個是用一個內(nèi)存BIO和 i2d_XXX_bio()或 d2i_XX_bio()一起使用,
另一個是你可以直接使用 i2d_XXX(),d2i_XXX() 函數(shù).
因為這個問題是最常見的導(dǎo)致痛苦的問題,所以我們在這里包含了一個使用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 字節(jié)的 p7的DER編碼.
反過來,假設(shè)我們在 buf 里已經(jīng)有 len 字節(jié)的數(shù)據(jù):
unsigned char *p;
p = buf;
p7 = d2i_PKCS7(NULL, &p, len);
這個時候 p7 包含一個有效的 PKCS7 結(jié)構(gòu),如果發(fā)生錯誤則是一個 NULL.
如果有錯誤發(fā)生, ERR_print_errors(bio) 應(yīng)該能給出更多信息.
使用臨時變量 'p' 是因為 ASN1 函數(shù)把傳入的指針增一,這樣它就做好
讀寫下一個結(jié)構(gòu)的準(zhǔn)備了.這樣常常會導(dǎo)致問題:如果不用臨時變量,
那么緩沖區(qū)指針就會剛好指向正在被讀寫的數(shù)據(jù)的后面.而那個地方很可能是
未初始化的數(shù)據(jù),而且如果試圖釋放該緩沖區(qū)就有可能會導(dǎo)致不可預(yù)料的后果,
因為它不再指向同一個地址.?
* 我想使用 這樣的宏,但卻給我一個錯誤,為什么?
通常在你用一個C++編譯器編譯某些使用PKCS#12宏的東西的時候會出現(xiàn)這個現(xiàn)象.
在程序里幾乎沒有使用PKCS#12的機會,分析和創(chuàng)建PKCS#12文件的更簡單的方法是
使用在 doc/openssl.txt 里有文檔的 PKCS12_parse() 和 PKCS12_create()函數(shù),
在 demos/pkcs12 里有例子.'pkcs12' 應(yīng)用程序必須使用該宏是因為它打印出
調(diào)試信息.
* 我調(diào)用了 <某個函數(shù)> 但是卻失敗了,為什么?
在提交一個報告或者在郵件列表里詢問某人之前,你應(yīng)該試著先判斷原因.
尤其是你應(yīng)該在失敗調(diào)用后調(diào)用ERR_print_errors() 或者 ERR_print_errors_fp()
然后看看該信息是否有助于你解決問題.不過要注意的是問題發(fā)生的地方可能比你
認(rèn)為的地方
要早--如果可能地話,你應(yīng)該在每個調(diào)用后面檢查錯誤,否則實際的問題可能會
被隱藏起來,因為有些 OpenSSL 函數(shù)會清理錯誤狀態(tài).
* 我的錯誤輸出只是一大堆數(shù)字,它們是什么意思?
實際的格式在 ERR_print_errors() 手冊頁里描述.
你應(yīng)該先調(diào)用函數(shù) ERR_load_crypto_strings() ,這樣信息就會以文本形式輸出.
如果你做不到這一點(比如那是預(yù)先編譯好了的二進(jìn)制),你可以直接在錯誤
碼(第二個冒號后面的十六進(jìn)制數(shù))上使用 errstr 工具.
* 為什么我收到什么未知算法的錯誤信息?
在好幾種情況下都有可能發(fā)生這樣的問題,比如讀取一個加密了的私鑰文件
或者試圖解密一個 PKCS#12 文件等.原因是忘了用OpenSSL_add_all_algorithms()
裝載OpenSSL 的算法表.參閱手冊頁獲取更多信息.
* 怎么創(chuàng)建證書或者認(rèn)證請求?
看看CA.pl(1)的手冊頁.它是一個封裝了'req','verify','ca'和'pkcs12'工具的
簡單容器.想要獲得更好的控制,請檢查相應(yīng)的獨立工具的手冊頁以及證書擴展
文檔(目前在 doc/openssl.txt).
* 我為什么不能創(chuàng)建認(rèn)證請求?
通常你看到的錯誤是:
unable to find 'distinguished_name' in config
problems making Certificate Request
這是因為程序找不到配置文件.請察看 req(1) 的 DIAGNOSTICS 節(jié)獲取更多信息.
* 為什么 會因為證書認(rèn)證錯誤而失敗?
這個問題通常是由日志信息標(biāo)識出來的,日志會象
"unable to get local issuer certificate" 或者 "self signed certificate" 這樣.
當(dāng)我們驗證一個證書的時候,其根CA必須被OpenSSL"信任",通常這就意味著該CA的證書
必須放在一個目錄或者文件中,而且相關(guān)的程序還要配置成讀取它.
OpenSSL 的程序 'verify' 表現(xiàn)得類似這個性質(zhì),并且發(fā)出類似的錯誤信息:
請查閱 verify(1) 程序的手冊頁獲取更多信息.
* 為什么我與使用OpenSSL的服務(wù)器聯(lián)接的時候總是只能使用弱加密?
幾乎肯定是因為你使用了老舊的"出口級"的瀏覽器,它們只支持弱加密.升級你的
瀏覽器以支持128位加密.
* 我怎樣才能創(chuàng)建DSA證書?
檢查 CA.pl(1) 的手冊頁獲取DSA證書的例子.
* 為什么我不能和一臺使用DSA證書的服務(wù)器建立SSL聯(lián)接?
通常你會看到一條信息說沒有共享的加密套件,而同樣的設(shè)置用RSA證書跑得很好.
有兩個可能原因.首先是客戶端可能不支持于DSA服務(wù)器的聯(lián)接,大多數(shù)web瀏覽器
(包括 Netscape 和 MSIE)都只支持與使用RSA加密套件的服務(wù)器聯(lián)接.
另外一個原因是沒有給服務(wù)器提供一套DH參數(shù).DH參數(shù)可以用 dhparam(1) 命令
創(chuàng)建然后用 SSL_CTX_set_tmp_dh() 裝載,例子可以看:
app/s_server.c 里的 s_server 的源程序.
* 我怎么才能刪除一個私鑰上的口令保護(hù)?
首先你必須絕對確信你想這么做.讓一個私鑰不加加密地存在是一個首要的安全
漏洞.如果你決定要這么做,請查看 rsa(1) 和 dsa(1) 的手冊頁.
* 為什么OpenSSH 的 configure 腳本不能檢測到 OpenSSL?
在 OpenSSH 1.2.2p1 里有個毛病,就是 configure 腳本不能找到安裝的 OpenSSL 庫.
這個問題實際上是個小毛病,很容易修補,只要給 OpenSSH 發(fā)布打下面的一個補丁就行了:
----- 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")
的時候被觸發(fā).返回的信息是"bc: 1 not implemented".對付這個問題的最好的方法
是找另外一個 bc 的實現(xiàn)然后編譯/安裝之.比如,GNU bc(見
http://www.gnu.org/software/software.html 獲取下載指導(dǎo))就可以很好地使用.
* 為什么 OpenSSL 在 Alpha True64 Unix 上編譯失敗?
在一些運行True64 Unix 和 Compaq C 的 Alpha 安裝上,編譯 crypto/sha/sha_dgst.c
會出錯,錯誤信息是'Fatal: Insufficient virtual memory to continue compilation.'
從我們的測試看來,這個臭蟲好象來自編譯器.現(xiàn)象是它使用了大量的駐留內(nèi)存編譯某些
東西,很可能是一個表.問題很明顯地來自優(yōu)化代碼,因為如果我們完全不進(jìn)行優(yōu)化(-O0)
那么編譯就可以通過(并且編譯器只使用了大概 2MB 駐留內(nèi)存,而不是 24MB 或者你的
當(dāng)前極限).
有三個解決方法:
1. 把你當(dāng)前數(shù)據(jù)段的大小的軟限制設(shè)得高一些.我們的經(jīng)驗表明在AlphaServer DS10上大約
241000 KB 就夠了.你可以用命令 'ulimit -Sd nnnnnn' 實現(xiàn)這些,這里 'nnnnnn' 是
把限制值設(shè)置的 KB 數(shù).
2. 如果你有一個比你需要的數(shù)量低的硬限制,而且你不能改變它,你可以用 -O0
做為優(yōu)化級別來編譯 OpenSSL.不過這樣做對那些希望從 OpenSSL 中獲取最大性能
的人來說不是特別好.更復(fù)雜一點兒的解決方法是否下面的方法:
----- 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,而其它的仍然用配置過程選取的優(yōu)化級別.當(dāng)完成
上面的工作后,進(jìn)行測試和安裝,最后你就成了.
* 為什么 OpenSSL 帶著"ar: command not found" 這樣的錯誤信息編譯失敗?
在 Solaris 2 上常見這個問題,因為 Sun 把 'ar' 和其它開發(fā)命令隱藏在一個
缺省時不在 $PATH 的目錄里了.其中一個目錄是 '/usr/ccs/bin'.修補這個問題的
最快手段是按照下面的方法做(假設(shè)你使用的是 sh 或者任意 sh 兼容的 shell):
----- snip:start -----
PATH=${PATH}:/usr/ccs/bin; export PATH
----- snip:end -----
然后重新編譯.你實際上要做的是確保 '/usr/ccs/bin' 永久地存在于你的 $PATH 里,
比如通過你的 '.profile' 文件(同樣,假設(shè)你使用一個 sh 兼容的 shell).
交易,這時Web頁面上需要傳輸重要或敏感的數(shù)據(jù),例如用戶的銀行帳戶、密碼等,所以網(wǎng)絡(luò)安全
就成為現(xiàn)代計算機網(wǎng)絡(luò)應(yīng)用急需解決的問題。
現(xiàn)行網(wǎng)上銀行和電子商務(wù)等大型的網(wǎng)上交易系統(tǒng)普遍采用HTTP和SSL相結(jié)合的方式。服務(wù)器端采用
支持SSL的Web服務(wù)器,用戶端采用支持SSL的瀏覽器實現(xiàn)安全通信。
SSL是Secure Socket Layer(安全套接層協(xié)議)的縮寫,可以在Internet上提供秘密性傳輸。
Netscape公司在推出第一個Web瀏覽器的同時,提出了SSL協(xié)議標(biāo)準(zhǔn),目前已有3.0版本。SSL采用公
開密鑰技術(shù)。其目標(biāo)是保證兩個應(yīng)用間通信的保密性和可靠性,可在服務(wù)器端和用戶端同時實現(xiàn)支
持。目前,利用公開密鑰技術(shù)的SSL協(xié)議,已成為Internet上保密通訊的工業(yè)標(biāo)準(zhǔn)。本文著重在
SSL協(xié)議和SSL程序設(shè)計兩方面談?wù)勛髡邔SL的理解。
SSL協(xié)議初步介紹
安全套接層協(xié)議能使用戶/服務(wù)器應(yīng)用之間的通信不被攻擊者,并且始終對服務(wù)器進(jìn)行認(rèn)證,
還可選擇對用戶進(jìn)行認(rèn)證。SSL協(xié)議要求建立在可靠的傳輸層協(xié)議(TCP)之上。SSL協(xié)議的優(yōu)勢在于
它是與應(yīng)用層協(xié)議獨立無關(guān)的,高層的應(yīng)用層協(xié)議(例如:HTTP,F(xiàn)TP,TELNET等)能透明地建立于
SSL協(xié)議之上。SSL協(xié)議在應(yīng)用層協(xié)議通信之前就已經(jīng)完成加密算法、通信密鑰的協(xié)商及服務(wù)器認(rèn)證
工作。在此之后應(yīng)用層協(xié)議所傳送的數(shù)據(jù)都會被加密,從而保證通信的私密性。
通過以上敘述,SSL協(xié)議提供的安全信道有以下三個特性:
1.數(shù)據(jù)的保密性
信息加密就是把明碼的輸入文件用加密算法轉(zhuǎn)換成加密的文件以實現(xiàn)數(shù)據(jù)的保密。加密的過程需要
用到密匙來加密數(shù)據(jù)然后再解密。沒有了密鑰,就無法解開加密的數(shù)據(jù)。數(shù)據(jù)加密之后,只有密匙
要用一個安全的方法傳送。加密過的數(shù)據(jù)可以公開地傳送。
2.數(shù)據(jù)的一致性
加密也能保證數(shù)據(jù)的一致性。例如:消息驗證碼(MAC),能夠校驗用戶提供的加密信息,接收者可
以用MAC來校驗加密數(shù)據(jù),保證數(shù)據(jù)在傳輸過程中沒有被篡改過。
3.安全驗證
加密的另外一個用途是用來作為個人的標(biāo)識,用戶的密匙可以作為他的安全驗證的標(biāo)識。
SSL是利用公開密鑰的加密技術(shù)(RSA)來作為用戶端與服務(wù)器端在傳送機密資料時的加密通訊協(xié)定。
目前,大部分的Web 服務(wù)器及瀏覽器都廣泛支持SSL 技術(shù)。當(dāng)瀏覽器試圖連接一個具有SSL認(rèn)證加
密的服務(wù)器時,就會喚醒一個SSL會話,瀏覽器檢查認(rèn)證,必須具備下面三個條件:
1)有一個權(quán)威機構(gòu)發(fā)放證書,當(dāng)然可以創(chuàng)建自我簽訂的證書(x509 結(jié)構(gòu))。
2)證書不能過期。
3)證書是屬于它所連接的服務(wù)器的。
只有全部具備了這三個條件,瀏覽器才能成功完成認(rèn)證。通過這三個條件,用戶能確認(rèn)其瀏覽器連接
到正確的服務(wù)器,而不是連接到一些想盜取用戶密碼等重要信息的虛假的服務(wù)器上。
在當(dāng)今的電子商務(wù)中還有一項被廣泛使用的安全協(xié)議是SET協(xié)議。SET(Secure Electronic Transaction,
安全電子交易)協(xié)議是由VISA和MasterCard兩大信用卡公司于1997年5月聯(lián)合推出的規(guī)范。SET能在電
子交易環(huán)節(jié)上提供更大的信任度、更完整的交易信息、更高的安全性和更少受欺詐的可能性。SET交
易分三個階段進(jìn)行:用戶向商家購物并確定支付;商家與銀行核實;銀行向商家支付貨款。每個階段都
涉及到RSA對數(shù)據(jù)加密,以及RSA數(shù)字簽名。使用SET協(xié)議,在一次交易中,要完成多次加密與解密操作,
故有很高的安全性,但SET協(xié)議比SSL協(xié)議復(fù)雜,商家和銀行都需要改造系統(tǒng)以實現(xiàn)互操作。
在Linux 下,比較流行支持SSL認(rèn)證的是OpenSSL服務(wù)器。OpenSSL項目是一個合作的項目,開發(fā)一個
健壯的、商業(yè)等級的、完整的開放源代碼的工具包,用強大的加密算法來實現(xiàn)安全的Socket層
(Secure Sockets Layer,SSL v2/v3)和傳輸層的安全性(Transport Layer Security,TLS v1)。
這個項目是由全世界的志愿者管理和開發(fā)OpenSSL工具包和相關(guān)文檔。
如何在Linux下配置OpenSSL服務(wù)器,首先從OpenSSL的主頁(http://www.openssl.org/)上下載
openssl-version.tar.gz軟件包來編譯安裝,與Apache服務(wù)器配合可以建立支持SSL的Web服務(wù)器,
并可以使用自我簽訂的證書做認(rèn)證,關(guān)于如何編譯、安裝OpenSSL服務(wù)器,可以參考一下OpenSSL HOWTO
文檔。
SSL 程序設(shè)計初步介紹
SSL 通訊模型為標(biāo)準(zhǔn)的C/S 結(jié)構(gòu),除了在 TCP 層之上進(jìn)行傳輸之外,與一般的通訊沒有什么明顯的區(qū)
別。在這里,我們主要介紹如何使用OpenSSL進(jìn)行安全通訊的程序設(shè)計。關(guān)于OpenSSL 的一些詳細(xì)的信
息請參考OpenSSL的官方主頁 http://www.openssl.org。
在使用OpenSSL前,必須先對OpenSSL 進(jìn)行初始化,以下的三個函數(shù)任選其一:
SSL_library_init(void);
OpenSSL_add_ssl_algorithms();
SSLeay_add_ssl_algorithms();
事實上 后面的兩個函數(shù)只是第一個函數(shù)的宏。
如果要使用OpenSSL的出錯信息,使用SSL_load_error_strings (void)進(jìn)行錯誤信息的初始化。以后
可以使用void ERR_print_errors_fp(FILE *fp) 打印SSL的錯誤信息。
一次SSL連接會話一般要先申請一個SSL 環(huán)境,基本的過程是:
1. SSL_METHOD* meth = TLSv1_client_method(); 創(chuàng)建本次會話連接所使用的協(xié)議,如果是客戶端可
以使用
SSL_METHOD* TLSv1_client_method(void); TLSv1.0 協(xié)議
SSL_METHOD* SSLv2_client_method(void); SSLv2 協(xié)議
SSL_METHOD* SSLv3_client_method(void); SSLv3 協(xié)議
SSL_METHOD* SSLv23_client_method(void); SSLv2/v3 協(xié)議
服務(wù)器同樣需要創(chuàng)建本次會話所使用的協(xié)議:
SSL_METHOD *TLSv1_server_method(void);
SSL_METHOD *SSLv2_server_method(void);
SSL_METHOD *SSLv3_server_method(void);
SSL_METHOD *SSLv23_server_method(void);
需要注意的是客戶端和服務(wù)器需要使用相同的協(xié)議。
2.申請SSL會話的環(huán)境 CTX,使用不同的協(xié)議進(jìn)行會話,其環(huán)境也是不同的。申請SSL會話環(huán)
境的OpenSSL函數(shù)是
SSLK_CTX* SSL_CTX_new (SSL_METHOD*); 參數(shù)就是前面我們申請的 SSL通訊方式。返回當(dāng)前
的SSL 連接環(huán)境的指針。
然后根據(jù)自己的需要設(shè)置CTX的屬性,典型的是設(shè)置SSL 握手階段證書的驗證方式和加載自己
的證書。
void SSL_CTX_set_verify (SSL_CTX* , int , int* (int, X509_STORE_CTX*) )
設(shè)置證書驗證的方式。
第一個參數(shù)是當(dāng)前的CTX 指針,第二個是驗證方式,如果是要驗證對方的話,就使用
SSL_VERIFY_PEER。不需要的話,使用SSL_VERIFY_NONE.一般情況下,客戶端需要驗證對方,而
服務(wù)器不需要。第三個參數(shù)是處理驗證的回調(diào)函數(shù),如果沒有特殊的需要,使用空指針就可以了。
void SSL_CTX_load_verify_locations(SSL_CTX*, const char* , const char*);
加載證書;
第一個參數(shù)同上,參數(shù)二是證書文件的名稱,參數(shù)三是證書文件的路徑;
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
加載本地的證書;type 指明證書文件的結(jié)構(gòu)類型;失敗返回-1
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
加載自己的私鑰;type 參數(shù)指明私鑰文件的結(jié)構(gòu)類型;失敗返回-1
加載了證書和文件之后,就可以驗證私鑰和證書是否相符:
BOOl SSL_CTX_check_private_key (SSL_CTX*);
3.既然SSL 使用TCP 協(xié)議,當(dāng)然需要把SSL attach 到已經(jīng)連接的套接字上了:
SSL* SSL_new (SSL_CTX*); 申請一個SSL 套節(jié)字;
int SSL_set_rfd (SSL*); 綁定只讀套接字
int SSL_set_wfd (SSL*); 綁定只寫套接字
int SSL_set_fd ( SSL*); 綁定讀寫套接字
綁定成功返回 1, 失敗返回0;
4. 接下來就是SSL 握手的動作了
int SSL_connect (SSL*); 失敗返回 -1
5. 握手成功之后,就可以進(jìn)行通訊了,使用SSL_read 和SS_write 讀寫SSL 套接字代替?zhèn)鹘y(tǒng)的
read 、write
int SSL_read (SSL *ssl, char *buf, int num );
int SSL_write (SSL *ssl, char *buf, int num);
如果是服務(wù)器,則使用 SSL_accept 代替?zhèn)鹘y(tǒng)的 accept 調(diào)用
int SSL_accept(SSL *ssl);
6. 通訊結(jié)束,需要釋放前面申請的 SSL資源
int SSL_shutdown(SSL *ssl); 關(guān)閉SSL套接字;
void SSL_free (ssl); 釋放SSL套接字;
void SSL_CTX_free (ctx); 釋放SSL環(huán)境;
OpenSSL 雖然已經(jīng)發(fā)展到了0.9.96版本,但是它的文檔還很少,甚至連最基本的man 函數(shù)手
冊都沒有完成。所以,本文緊緊是講述了使用OpenSSL 進(jìn)行程序設(shè)計的框架。更加詳細(xì)的資
料可以參考OpenSSL 的文檔或者 Apache mod_ssl 的文檔。
通過以上的介紹,我想讀者對SSL協(xié)議已經(jīng)有了一定的了解,作者有機會將會繼續(xù)給大家介紹
SSL協(xié)議的其他方面的內(nèi)容。
SSL原理解密
本文出自:
http://noc.cstnet.net.cn/
范曉明
RSA公鑰加密在計算機產(chǎn)業(yè)中被廣泛使用在認(rèn)證和加密。可以從RSA Data Security Inc.獲得的RSA公鑰加密許可證。公鑰加密是使用一對非對稱的密碼加密或解密的方法。每一對密碼由公鑰和私鑰組成。公鑰被廣泛發(fā)布。私鑰是隱密的,不 公開。用公鑰加密的數(shù)據(jù)只能夠被私鑰解密。反過來,使用私鑰加密的數(shù)據(jù)只能用公鑰解密。這個非對稱的特性使得公鑰加密很有用。
使用公鑰加密法認(rèn)證
認(rèn)證是一個身份認(rèn)證的過程。在下列例子中包括甲和乙,公鑰加密會非常輕松地校驗身份。符號{數(shù)據(jù)} key意味著"數(shù)據(jù)"已經(jīng)使用密碼加密或解密。假如甲想校驗乙的身份。乙有一對密碼,一個是公開的,另一個是私有的。乙透露給甲他的公鑰。甲產(chǎn)生一個隨機 信息發(fā)送給乙。甲——〉乙:random-message
乙使用他的私鑰加密消息,返回甲加密后的消息。 乙——〉甲:{random-message}乙的私鑰
甲收到這個消息然后使用乙的以前公開過的公鑰解密。他比較解密后的消息與他原先發(fā)給乙的消息。如果它們完全一致,就會知道在與乙說話。任意一個中間人不會知道乙的私鑰,也不能正確加密甲檢查的隨機消息。
除非你清楚知道你加密的消息。用私鑰加密消息,然后發(fā)送給其他人不是一個好主意。因為加密值可能被用來對付你,需要注意的是:因為只有你才有私鑰,所以只 有你才能加密消息。所以,代替加密甲發(fā)來的原始消息,乙創(chuàng)建了一個信息段并且加密。信息段取自隨機消息(random-message)并具有以下有用的 特性:
1. 這個信息段難以還原。任何人即使偽裝成乙,也不能從信息段中得到原始消息;
2. 假冒者將發(fā)現(xiàn)不同的消息計算出相同的信息段值;
3. 使用信息段,乙能夠保護(hù)自己。他計算甲發(fā)出的隨機信息段,并且加密結(jié)果,并發(fā)送加密信息段返回甲。甲能夠計算出相同的信息段并且解密乙的消息認(rèn)證乙。
這個技術(shù)僅僅描繪了數(shù)字簽名。通過加密甲產(chǎn)生的隨機消息,乙已經(jīng)在甲產(chǎn)生的消息簽名。因此我們的認(rèn)證協(xié)議還需要一次加密。一些消息由乙產(chǎn)生:
甲——〉乙:你好,你是乙么?
乙——〉甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
當(dāng)你使用這個協(xié)議,乙知道他發(fā)送給乙的消息,他不介意在上面簽名。他先發(fā)送不加密的信息,"甲,我是乙。",然后發(fā)送信息段加密的消息版本。甲可以非常方便地校驗乙就是乙,同時,乙還沒有在他不想要的信息上簽名。
提交公鑰
那么,乙怎樣以可信的方式提交他的公鑰呢?看看認(rèn)證協(xié)議如下所示:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的公鑰
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] } 乙的私鑰
在這個協(xié)議下,任何人都能夠成為"乙"。所有你所要的只是公鑰和私鑰。你發(fā)送給甲說你就是乙,這樣你的公鑰就代替了乙的密碼。然后,你發(fā)送用你的私鑰加密的消息,證明你的身份。甲卻不能發(fā)覺你并不是乙。為了解決這個問題,標(biāo)準(zhǔn)組織已經(jīng)發(fā)明了證書。一個證書有以下的內(nèi)容:
* 證書的發(fā)行者姓名
* 發(fā)行證書的組織
* 標(biāo)題的公鑰
* 郵戳
證書使用發(fā)行者的私鑰加密。每一個人都知道證書發(fā)行者的公鑰(這樣,每個證書的發(fā)行者擁有一個證書)。證書是一個把公鑰與姓名綁定的協(xié)議。通過使用證書技術(shù),每一個人都可以檢查乙的證書,判斷是否被假冒。假設(shè)乙控制好他的私鑰,并且他確實是得到證書的乙,就萬事大吉了。
這些是修訂后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲, 我是乙] } 乙的私鑰
現(xiàn)在當(dāng)甲收到乙的第一個消息,他能檢查證書,簽名(如上所述,使用信息段和公鑰解密),然后檢查標(biāo)題(乙的姓名),確定是乙。他就能相信公鑰就是乙的公鑰 和要求乙證明自己的身份。乙通過上面的過程,制作一個信息段,用一個簽名版本答復(fù)甲。甲可以校驗乙的信息段通過使用從證書上得到的公鑰并檢查結(jié)果。
如果一個黑客,叫H
甲——〉H:你好
H——〉不能建立一個令甲相信的從乙的消息。
交換密碼(secret)
一旦甲已經(jīng)驗證乙后,他可以發(fā)送給乙一個只有乙可以解密、閱讀的消息:
甲——〉乙:{secret}乙的公鑰
唯一找到密碼的方法只有使用乙的私鑰解碼上述的信息。交換密碼是另一個有效使用密碼加密的方法。即使在甲和乙之間的通訊被偵聽,只有乙才能得到密碼。
使用密碼作為另一個secret-key增強了網(wǎng)絡(luò)的安全性,但是這次這是一個對稱的加密算法(例如DES、RC4、IDE甲)。因為甲在發(fā)送給乙之前產(chǎn) 生了密碼,所以甲知道密碼。乙知道密碼因為乙有私鑰,能夠解密甲的信息。但他們都知道密碼,他們都能夠初始化一個對稱密碼算法,而且開始發(fā)送加密后的信 息。這兒是修定后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉乙:ok 乙,here is a secret {secret}乙的公鑰
乙——〉甲:{some message}secret-key
黑客
那么如果有一個惡意的黑客H在甲和乙中間,雖然不能發(fā)現(xiàn)甲和乙已經(jīng)交換的密碼,但能干擾他們的交談。他可以放過大部分信息,選擇破壞一定的信息(這是非常簡單的,因為他知道甲和乙通話采用的協(xié)議)。
甲——〉H:你好
H——〉乙:你好
乙——〉H:嗨,我是乙,乙的校驗
H——〉甲:嗨,我是乙,乙的校驗
甲——〉H:prove it
H——〉乙:prove it
乙——〉H:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
H——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉H:ok 乙,here is a secret {secret} 乙的公鑰
H——〉乙:ok 乙,here is a secret {secret} 乙的公鑰
乙——〉H:{some message}secret-key
H——〉甲:Garble[{some message}secret-key ]
H忽略一些數(shù)據(jù)不修改,直到甲和乙交換密碼。然后H干擾乙給甲的信息。在這一點上,甲相信乙,所以他可能相信已經(jīng)被干擾的消息并且盡力解密。
需要注意的是,H不知道密碼,他所能做的就是毀壞使用秘鑰加密后的數(shù)據(jù)。基于協(xié)議,H可能不能產(chǎn)生一個有效的消息。但下一次呢?
為了阻止這種破壞,甲和乙在他們的協(xié)議中產(chǎn)生一個校驗碼消息(message authentication code)。一個校驗碼消息(MAC)是一部分由密碼和一些傳輸消息產(chǎn)生的數(shù)據(jù)。信息段算法描述的上述特性正是它們抵御H的功能:
MAC= Digest[some message,secret ]
因為H不知道密碼,他不能得出正確的值。即使H隨機干擾消息,只要數(shù)據(jù)量大,他成功的機會微乎其微。例如,使用HD5(一個RSA發(fā)明的好的加密算法), 甲和乙能夠發(fā)送128位MAC值和他們的消息。H猜測正確的MAC的幾率將近1/18,446,744,073,709,551,616約等于零。
這是又一次修改后的協(xié)議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:嗨,我是乙,乙的校驗
甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
ok 乙,here is a secret {secret} 乙的公鑰
{some message,MAC}secret-key
現(xiàn)在H已經(jīng)無技可施了。他干擾了得到的所有消息,但MAC計算機能夠發(fā)現(xiàn)他。甲和乙能夠發(fā)現(xiàn)偽造的MAC值并且停止交談。H不再能與乙通訊。
OpenSSL FAQ
http://www.linuxforum.net
何偉平 譯
OpenSSL - 經(jīng)常問到的問題
--------------------------------------
* 目前的 OpenSSL 的版本是什么?
* 文檔在哪里?
* 我怎樣和 OpenSSL 的開發(fā)人員聯(lián)系?
* 要使用 OpenSSL 我需要申請專利許可證嗎?
* OpenSSL 線程安全嗎?
* 為什么我收到 "PRNG not seeded" 這樣的錯誤信息?
* 為什么鏈接器抱怨說有未定義的符號?
* 我在哪里能得到編譯好了的 OpenSSL 版本?
* 我在 Windows 下編譯了一個程序,可它崩潰了:為什么?
* 怎樣使用ASN1的函數(shù)讀寫DER編碼的緩沖區(qū)?
* 我想使用 這樣的宏,但卻給我一個錯誤,為什么?
* 我調(diào)用了 <某個函數(shù)> 但是卻失敗了,為什么?
* 我的錯誤輸出只是一大堆數(shù)字,它們是什么意思?
* 為什么我收到什么未知算法的錯誤信息?
* 怎么創(chuàng)建證書或者認(rèn)證請求?
* 我為什么不能創(chuàng)建認(rèn)證請求?
* 為什么 會因為證書認(rèn)證錯誤而失敗?
* 為什么我與使用OpenSSL的服務(wù)器聯(lián)接的時候總是只能使用弱加密?
* 我怎樣才能創(chuàng)建DSA證書?
* 為什么我不能和一臺使用DSA證書的服務(wù)器建立SSL聯(lián)接?
* 我怎么才能刪除一個私鑰上的口令保護(hù)?
* 為什么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 日發(fā)布.
除了當(dāng)前的穩(wěn)定版本以外,你還可以獲取 OpenSSL 的每日開發(fā)快照,在
,或者你也可以通過匿名 CVS 訪問
獲取.
* 文檔在哪里?
OpenSSL 是一個庫,它為類似安全 web 服務(wù)器這樣的應(yīng)用提供加密功能.
請仔細(xì)閱讀你想用的應(yīng)用的文檔.INSTALL 文件解釋了如何安裝這個庫的問題.
OpenSSL 包含一個可以用于執(zhí)行加密功能的命令行工具.在 openssl(1) 手冊頁
里有描述.給開發(fā)人員使用的文檔正在寫.有幾個手冊頁已經(jīng)可以用了;libcrypto
和 libssl 庫的概述在 crypto(3) 和 ssl(3)的手冊頁里描述.
OpenSSL 手冊頁安裝在 /usr/local/ssl/man (或者你象 INSTALL 里描述的那樣聲明
的另外一個目錄).另外,你可以在閱讀大多數(shù)
當(dāng)前版本的文檔.
有關(guān) libcrypto 里面的部件的更多內(nèi)容,你可以閱讀 Ariel Glenn 的關(guān)于 SSLeay 0.9
的文檔,它是 OpenSSL 的前身,它的文檔在
那些文檔中有許多仍然適用于 OpenSSL.
在 doc/openssl.txt 里有一些關(guān)于證書擴展和 PKCS#12 的文檔.
最早的 SSLeay 的文檔放在 OpenSSL 的 doc/ssleay.txt 里.如果其他的資源都
不能幫助你的話,那么它也許有用,不過你一定要知道它反映的是過時的 SSLeay
0.6.6 的版本.
* 我怎樣和 OpenSSL 的開發(fā)人員聯(lián)系?
README 文件描述了如何向 OpenSSL 提交臭蟲報告和補丁.OpenSSL 郵件列表
的信息可以在 獲得.
* 要使用 OpenSSL 我需要申請專利許可證嗎?
README 文件的專利(patent)段列出了你使用OpenSSL時可能要遵循的專利.
請咨詢一位律師獲取關(guān)于版權(quán)的信息.OpenSSL 開發(fā)組不提供法律建議.
你可以配置你的 OpenSSL 不使用 RC5 和 IDEA.用下面的命令:
./config no-rc5 no-idea
* OpenSSL 線程安全嗎?
是(有一個局限:一次 SSL 聯(lián)接不能使用多線程進(jìn)行并發(fā)).在 Windows 和許多
Unix 系統(tǒng)上,OpenSSL 自動使用標(biāo)準(zhǔn)庫的多線程版本.如果你的平臺不是這些平臺
之一,請參考 INSTALL 文件.
多線程應(yīng)用必須給 OpenSSL 提供兩個回調(diào)函數(shù).這些都在 thread(3) 手冊頁里描述.
* 為什么我收到 "PRNG not seeded" 這樣的錯誤信息?
加密軟件需要一個非周期的數(shù)據(jù)源才能正確運轉(zhuǎn).
許多開放源碼的操作系統(tǒng)提供一個"隨機設(shè)備"為這個用途服務(wù).而在其他系統(tǒng)上,
應(yīng)用在生成密鑰或者執(zhí)行公鑰加密之前必須用合適的數(shù)據(jù)調(diào)用 RAND_add()或
RAND_seed()函數(shù).
有些有缺陷的應(yīng)用不做這件事.到版本 0.9.5,OpenSSL 里面的需要隨機數(shù)
的函數(shù)如果在隨機數(shù)發(fā)生器沒有收到一個128位的隨機值就會報一個錯誤.
如果出現(xiàn)這個錯誤,請與你使用的應(yīng)用的作者聯(lián)系.很可能是他/她就沒有正確
使用這些東西.OpenSSL 0.9.5 和以后的版本會拒絕執(zhí)行那些有潛在的不安全加密
的動作,以此把錯誤顯示出來.
在沒有 /dev/urandom 的系統(tǒng)上,使用熵收集守護(hù)(Entropy Gathering Demon)
也是一個好計策);參閱 RAND_egd() 的手冊頁獲取細(xì)節(jié).
大多數(shù) openssl 的命令行工具會試圖使用文件 $HOME/.rnd (或者 $RANDFILE,
--如果設(shè)置了這個環(huán)境變量)用做產(chǎn)生 PRNG 種子.如果這個文件不存在或者太短,
就有可能出現(xiàn)那個 "PRNG not seeded" 錯誤信息.
[ OpenSSL 0.9.5 的用戶注意了:版本0.9.5的命令"openssl rsa"
并不做這件事,并且在那些沒有 /dev/urandom 的系統(tǒng)上用口令加密一個
RSA密鑰時會失效!這是一個庫里面的臭蟲;請使用更高版本的軟件.]
對于 Solaris 2.6 而言,Tim Nibbe 和另外一些人建議
安裝 SUNski 包.該包來自 Sun 補丁 105710-01 (Sparc),它會增加一個
/dev/random 設(shè)備并確保其投入使用,通常是通過 $RANDFILE.其他 Solaris
版本也可能有類似補丁.不過,我們必須警告你 /dev/random 通常是一個塊設(shè)備,
這一點可能對 OpenSSL 有些影響.
* 為什么鏈接器抱怨說有未定義的符號?
可能是因為編譯中斷了,而且 make 沒有認(rèn)識到還缺少某些東西.運行
"make clean; make".
如果你用的是 ./Configure 而不是 ./config,請確信你選用了正確的目標(biāo)機器.
在不同的 OS 版本之間的文件格式可能有些許區(qū)別(比如 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
如果這些東西都不能幫你解決問題,那你可以試試當(dāng)前的快照(源程序).
如果問題依舊,請?zhí)峤灰粋€錯誤報告.
* 我在哪里能得到編譯好了的 OpenSSL 版本?
有些使用 OpenSSL 的應(yīng)用是以二進(jìn)制的形式發(fā)布的.當(dāng)使用這樣的應(yīng)用時,
你不需要自己安裝 OpenSSL;該應(yīng)用會包含所需要的部分(比如,DLL)
如果你想在 Windows 系統(tǒng)上安裝 OpenSSL,但是你沒有 C 編譯器,請閱讀
INSTALL.W32 里的 "mingw32" 節(jié),獲取如何獲取和安裝自由的 GNU C 編譯器的信息.
許多 Linux 和 *BSD 發(fā)布版帶有 OpenSSL.
* 我在 Windows 下編譯了一個程序,可它崩潰了:為什么?
通常是因為你忽略了 INSTALL.W32 里的注解.你必須和多線程版本的 VC++ 運行時間
DLL 庫鏈接,否則沖突會導(dǎo)致程序崩潰:通常是在第一次 BIO 相關(guān)的讀寫操作的時候.
* 怎樣使用ASN1的函數(shù)讀寫DER編碼的緩沖區(qū)?
你有兩個選擇.一個是用一個內(nèi)存BIO和 i2d_XXX_bio()或 d2i_XX_bio()一起使用,
另一個是你可以直接使用 i2d_XXX(),d2i_XXX() 函數(shù).
因為這個問題是最常見的導(dǎo)致痛苦的問題,所以我們在這里包含了一個使用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 字節(jié)的 p7的DER編碼.
反過來,假設(shè)我們在 buf 里已經(jīng)有 len 字節(jié)的數(shù)據(jù):
unsigned char *p;
p = buf;
p7 = d2i_PKCS7(NULL, &p, len);
這個時候 p7 包含一個有效的 PKCS7 結(jié)構(gòu),如果發(fā)生錯誤則是一個 NULL.
如果有錯誤發(fā)生, ERR_print_errors(bio) 應(yīng)該能給出更多信息.
使用臨時變量 'p' 是因為 ASN1 函數(shù)把傳入的指針增一,這樣它就做好
讀寫下一個結(jié)構(gòu)的準(zhǔn)備了.這樣常常會導(dǎo)致問題:如果不用臨時變量,
那么緩沖區(qū)指針就會剛好指向正在被讀寫的數(shù)據(jù)的后面.而那個地方很可能是
未初始化的數(shù)據(jù),而且如果試圖釋放該緩沖區(qū)就有可能會導(dǎo)致不可預(yù)料的后果,
因為它不再指向同一個地址.?
* 我想使用 這樣的宏,但卻給我一個錯誤,為什么?
通常在你用一個C++編譯器編譯某些使用PKCS#12宏的東西的時候會出現(xiàn)這個現(xiàn)象.
在程序里幾乎沒有使用PKCS#12的機會,分析和創(chuàng)建PKCS#12文件的更簡單的方法是
使用在 doc/openssl.txt 里有文檔的 PKCS12_parse() 和 PKCS12_create()函數(shù),
在 demos/pkcs12 里有例子.'pkcs12' 應(yīng)用程序必須使用該宏是因為它打印出
調(diào)試信息.
* 我調(diào)用了 <某個函數(shù)> 但是卻失敗了,為什么?
在提交一個報告或者在郵件列表里詢問某人之前,你應(yīng)該試著先判斷原因.
尤其是你應(yīng)該在失敗調(diào)用后調(diào)用ERR_print_errors() 或者 ERR_print_errors_fp()
然后看看該信息是否有助于你解決問題.不過要注意的是問題發(fā)生的地方可能比你
認(rèn)為的地方
要早--如果可能地話,你應(yīng)該在每個調(diào)用后面檢查錯誤,否則實際的問題可能會
被隱藏起來,因為有些 OpenSSL 函數(shù)會清理錯誤狀態(tài).
* 我的錯誤輸出只是一大堆數(shù)字,它們是什么意思?
實際的格式在 ERR_print_errors() 手冊頁里描述.
你應(yīng)該先調(diào)用函數(shù) ERR_load_crypto_strings() ,這樣信息就會以文本形式輸出.
如果你做不到這一點(比如那是預(yù)先編譯好了的二進(jìn)制),你可以直接在錯誤
碼(第二個冒號后面的十六進(jìn)制數(shù))上使用 errstr 工具.
* 為什么我收到什么未知算法的錯誤信息?
在好幾種情況下都有可能發(fā)生這樣的問題,比如讀取一個加密了的私鑰文件
或者試圖解密一個 PKCS#12 文件等.原因是忘了用OpenSSL_add_all_algorithms()
裝載OpenSSL 的算法表.參閱手冊頁獲取更多信息.
* 怎么創(chuàng)建證書或者認(rèn)證請求?
看看CA.pl(1)的手冊頁.它是一個封裝了'req','verify','ca'和'pkcs12'工具的
簡單容器.想要獲得更好的控制,請檢查相應(yīng)的獨立工具的手冊頁以及證書擴展
文檔(目前在 doc/openssl.txt).
* 我為什么不能創(chuàng)建認(rèn)證請求?
通常你看到的錯誤是:
unable to find 'distinguished_name' in config
problems making Certificate Request
這是因為程序找不到配置文件.請察看 req(1) 的 DIAGNOSTICS 節(jié)獲取更多信息.
* 為什么 會因為證書認(rèn)證錯誤而失敗?
這個問題通常是由日志信息標(biāo)識出來的,日志會象
"unable to get local issuer certificate" 或者 "self signed certificate" 這樣.
當(dāng)我們驗證一個證書的時候,其根CA必須被OpenSSL"信任",通常這就意味著該CA的證書
必須放在一個目錄或者文件中,而且相關(guān)的程序還要配置成讀取它.
OpenSSL 的程序 'verify' 表現(xiàn)得類似這個性質(zhì),并且發(fā)出類似的錯誤信息:
請查閱 verify(1) 程序的手冊頁獲取更多信息.
* 為什么我與使用OpenSSL的服務(wù)器聯(lián)接的時候總是只能使用弱加密?
幾乎肯定是因為你使用了老舊的"出口級"的瀏覽器,它們只支持弱加密.升級你的
瀏覽器以支持128位加密.
* 我怎樣才能創(chuàng)建DSA證書?
檢查 CA.pl(1) 的手冊頁獲取DSA證書的例子.
* 為什么我不能和一臺使用DSA證書的服務(wù)器建立SSL聯(lián)接?
通常你會看到一條信息說沒有共享的加密套件,而同樣的設(shè)置用RSA證書跑得很好.
有兩個可能原因.首先是客戶端可能不支持于DSA服務(wù)器的聯(lián)接,大多數(shù)web瀏覽器
(包括 Netscape 和 MSIE)都只支持與使用RSA加密套件的服務(wù)器聯(lián)接.
另外一個原因是沒有給服務(wù)器提供一套DH參數(shù).DH參數(shù)可以用 dhparam(1) 命令
創(chuàng)建然后用 SSL_CTX_set_tmp_dh() 裝載,例子可以看:
app/s_server.c 里的 s_server 的源程序.
* 我怎么才能刪除一個私鑰上的口令保護(hù)?
首先你必須絕對確信你想這么做.讓一個私鑰不加加密地存在是一個首要的安全
漏洞.如果你決定要這么做,請查看 rsa(1) 和 dsa(1) 的手冊頁.
* 為什么OpenSSH 的 configure 腳本不能檢測到 OpenSSL?
在 OpenSSH 1.2.2p1 里有個毛病,就是 configure 腳本不能找到安裝的 OpenSSL 庫.
這個問題實際上是個小毛病,很容易修補,只要給 OpenSSH 發(fā)布打下面的一個補丁就行了:
----- 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")
的時候被觸發(fā).返回的信息是"bc: 1 not implemented".對付這個問題的最好的方法
是找另外一個 bc 的實現(xiàn)然后編譯/安裝之.比如,GNU bc(見
http://www.gnu.org/software/software.html 獲取下載指導(dǎo))就可以很好地使用.
* 為什么 OpenSSL 在 Alpha True64 Unix 上編譯失敗?
在一些運行True64 Unix 和 Compaq C 的 Alpha 安裝上,編譯 crypto/sha/sha_dgst.c
會出錯,錯誤信息是'Fatal: Insufficient virtual memory to continue compilation.'
從我們的測試看來,這個臭蟲好象來自編譯器.現(xiàn)象是它使用了大量的駐留內(nèi)存編譯某些
東西,很可能是一個表.問題很明顯地來自優(yōu)化代碼,因為如果我們完全不進(jìn)行優(yōu)化(-O0)
那么編譯就可以通過(并且編譯器只使用了大概 2MB 駐留內(nèi)存,而不是 24MB 或者你的
當(dāng)前極限).
有三個解決方法:
1. 把你當(dāng)前數(shù)據(jù)段的大小的軟限制設(shè)得高一些.我們的經(jīng)驗表明在AlphaServer DS10上大約
241000 KB 就夠了.你可以用命令 'ulimit -Sd nnnnnn' 實現(xiàn)這些,這里 'nnnnnn' 是
把限制值設(shè)置的 KB 數(shù).
2. 如果你有一個比你需要的數(shù)量低的硬限制,而且你不能改變它,你可以用 -O0
做為優(yōu)化級別來編譯 OpenSSL.不過這樣做對那些希望從 OpenSSL 中獲取最大性能
的人來說不是特別好.更復(fù)雜一點兒的解決方法是否下面的方法:
----- 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,而其它的仍然用配置過程選取的優(yōu)化級別.當(dāng)完成
上面的工作后,進(jìn)行測試和安裝,最后你就成了.
* 為什么 OpenSSL 帶著"ar: command not found" 這樣的錯誤信息編譯失敗?
在 Solaris 2 上常見這個問題,因為 Sun 把 'ar' 和其它開發(fā)命令隱藏在一個
缺省時不在 $PATH 的目錄里了.其中一個目錄是 '/usr/ccs/bin'.修補這個問題的
最快手段是按照下面的方法做(假設(shè)你使用的是 sh 或者任意 sh 兼容的 shell):
----- snip:start -----
PATH=${PATH}:/usr/ccs/bin; export PATH
----- snip:end -----
然后重新編譯.你實際上要做的是確保 '/usr/ccs/bin' 永久地存在于你的 $PATH 里,
比如通過你的 '.profile' 文件(同樣,假設(shè)你使用一個 sh 兼容的 shell).
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
