原文:http://blog.sina.com.cn/s/blog_4d97eecf0100090n.html
文章寫的不錯 趕緊備份下 謝謝原作者
隨著計算機網絡技術的發展,方便快捷的互連網使人們漸漸習慣了從Web頁上收發E-mail、購物和
交易,這時Web頁面上需要傳輸重要或敏感的數據,例如用戶的銀行帳戶、密碼等,所以網絡安全
就成為現代計算機網絡應用急需解決的問題。
現行網上銀行和電子商務等大型的網上交易系統普遍采用HTTP和SSL相結合的方式。服務器端采用
支持SSL的Web服務器,用戶端采用支持SSL的瀏覽器實現安全通信。
SSL是Secure Socket Layer(安全套接層協議)的縮寫,可以在Internet上提供秘密性傳輸。
Netscape公司在推出第一個Web瀏覽器的同時,提出了SSL協議標準,目前已有3.0版本。SSL采用公
開密鑰技術。其目標是保證兩個應用間通信的保密性和可靠性,可在服務器端和用戶端同時實現支
持。目前,利用公開密鑰技術的SSL協議,已成為Internet上保密通訊的工業標準。本文著重在
SSL協議和SSL程序設計兩方面談談作者對SSL的理解。
SSL協議初步介紹
安全套接層協議能使用戶/服務器應用之間的通信不被攻擊者,并且始終對服務器進行認證,
還可選擇對用戶進行認證。SSL協議要求建立在可靠的傳輸層協議(TCP)之上。SSL協議的優勢在于
它是與應用層協議獨立無關的,高層的應用層協議(例如:HTTP,FTP,TELNET等)能透明地建立于
SSL協議之上。SSL協議在應用層協議通信之前就已經完成加密算法、通信密鑰的協商及服務器認證
工作。在此之后應用層協議所傳送的數據都會被加密,從而保證通信的私密性。
通過以上敘述,SSL協議提供的安全信道有以下三個特性:
1.數據的保密性
信息加密就是把明碼的輸入文件用加密算法轉換成加密的文件以實現數據的保密。加密的過程需要
用到密匙來加密數據然后再解密。沒有了密鑰,就無法解開加密的數據。數據加密之后,只有密匙
要用一個安全的方法傳送。加密過的數據可以公開地傳送。
2.數據的一致性
加密也能保證數據的一致性。例如:消息驗證碼(MAC),能夠校驗用戶提供的加密信息,接收者可
以用MAC來校驗加密數據,保證數據在傳輸過程中沒有被篡改過。
3.安全驗證
加密的另外一個用途是用來作為個人的標識,用戶的密匙可以作為他的安全驗證的標識。
SSL是利用公開密鑰的加密技術(RSA)來作為用戶端與服務器端在傳送機密資料時的加密通訊協定。
目前,大部分的Web 服務器及瀏覽器都廣泛支持SSL 技術。當瀏覽器試圖連接一個具有SSL認證加
密的服務器時,就會喚醒一個SSL會話,瀏覽器檢查認證,必須具備下面三個條件:
1)有一個權威機構發放證書,當然可以創建自我簽訂的證書(x509 結構)。
2)證書不能過期。
3)證書是屬于它所連接的服務器的。
只有全部具備了這三個條件,瀏覽器才能成功完成認證。通過這三個條件,用戶能確認其瀏覽器連接
到正確的服務器,而不是連接到一些想盜取用戶密碼等重要信息的虛假的服務器上。
在當今的電子商務中還有一項被廣泛使用的安全協議是SET協議。SET(Secure Electronic Transaction,
安全電子交易)協議是由VISA和MasterCard兩大信用卡公司于1997年5月聯合推出的規范。SET能在電
子交易環節上提供更大的信任度、更完整的交易信息、更高的安全性和更少受欺詐的可能性。SET交
易分三個階段進行:用戶向商家購物并確定支付;商家與銀行核實;銀行向商家支付貨款。每個階段都
涉及到RSA對數據加密,以及RSA數字簽名。使用SET協議,在一次交易中,要完成多次加密與解密操作,
故有很高的安全性,但SET協議比SSL協議復雜,商家和銀行都需要改造系統以實現互操作。
在Linux 下,比較流行支持SSL認證的是OpenSSL服務器。OpenSSL項目是一個合作的項目,開發一個
健壯的、商業等級的、完整的開放源代碼的工具包,用強大的加密算法來實現安全的Socket層
(Secure Sockets Layer,SSL v2/v3)和傳輸層的安全性(Transport Layer Security,TLS v1)。
這個項目是由全世界的志愿者管理和開發OpenSSL工具包和相關文檔。
如何在Linux下配置OpenSSL服務器,首先從OpenSSL的主頁(http://www.openssl.org/)上下載
openssl-version.tar.gz軟件包來編譯安裝,與Apache服務器配合可以建立支持SSL的Web服務器,
并可以使用自我簽訂的證書做認證,關于如何編譯、安裝OpenSSL服務器,可以參考一下OpenSSL HOWTO
文檔。
SSL 程序設計初步介紹
SSL 通訊模型為標準的C/S 結構,除了在 TCP 層之上進行傳輸之外,與一般的通訊沒有什么明顯的區
別。在這里,我們主要介紹如何使用OpenSSL進行安全通訊的程序設計。關于OpenSSL 的一些詳細的信
息請參考OpenSSL的官方主頁 http://www.openssl.org。
在使用OpenSSL前,必須先對OpenSSL 進行初始化,以下的三個函數任選其一:
SSL_library_init(void);
OpenSSL_add_ssl_algorithms();
SSLeay_add_ssl_algorithms();
事實上 后面的兩個函數只是第一個函數的宏。
如果要使用OpenSSL的出錯信息,使用SSL_load_error_strings (void)進行錯誤信息的初始化。以后
可以使用void ERR_print_errors_fp(FILE *fp) 打印SSL的錯誤信息。
一次SSL連接會話一般要先申請一個SSL 環境,基本的過程是:
1. SSL_METHOD* meth = TLSv1_client_method(); 創建本次會話連接所使用的協議,如果是客戶端可
以使用
SSL_METHOD* TLSv1_client_method(void); TLSv1.0 協議
SSL_METHOD* SSLv2_client_method(void); SSLv2 協議
SSL_METHOD* SSLv3_client_method(void); SSLv3 協議
SSL_METHOD* SSLv23_client_method(void); SSLv2/v3 協議
服務器同樣需要創建本次會話所使用的協議:
SSL_METHOD *TLSv1_server_method(void);
SSL_METHOD *SSLv2_server_method(void);
SSL_METHOD *SSLv3_server_method(void);
SSL_METHOD *SSLv23_server_method(void);
需要注意的是客戶端和服務器需要使用相同的協議。
2.申請SSL會話的環境 CTX,使用不同的協議進行會話,其環境也是不同的。申請SSL會話環
境的OpenSSL函數是
SSLK_CTX* SSL_CTX_new (SSL_METHOD*); 參數就是前面我們申請的 SSL通訊方式。返回當前
的SSL 連接環境的指針。
然后根據自己的需要設置CTX的屬性,典型的是設置SSL 握手階段證書的驗證方式和加載自己
的證書。
void SSL_CTX_set_verify (SSL_CTX* , int , int* (int, X509_STORE_CTX*) )
設置證書驗證的方式。
第一個參數是當前的CTX 指針,第二個是驗證方式,如果是要驗證對方的話,就使用
SSL_VERIFY_PEER。不需要的話,使用SSL_VERIFY_NONE.一般情況下,客戶端需要驗證對方,而
服務器不需要。第三個參數是處理驗證的回調函數,如果沒有特殊的需要,使用空指針就可以了。
void SSL_CTX_load_verify_locations(SSL_CTX*, const char* , const char*);
加載證書;
第一個參數同上,參數二是證書文件的名稱,參數三是證書文件的路徑;
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
加載本地的證書;type 指明證書文件的結構類型;失敗返回-1
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
加載自己的私鑰;type 參數指明私鑰文件的結構類型;失敗返回-1
加載了證書和文件之后,就可以驗證私鑰和證書是否相符:
BOOl SSL_CTX_check_private_key (SSL_CTX*);
3.既然SSL 使用TCP 協議,當然需要把SSL attach 到已經連接的套接字上了:
SSL* SSL_new (SSL_CTX*); 申請一個SSL 套節字;
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. 握手成功之后,就可以進行通訊了,使用SSL_read 和SS_write 讀寫SSL 套接字代替傳統的
read 、write
int SSL_read (SSL *ssl, char *buf, int num );
int SSL_write (SSL *ssl, char *buf, int num);
如果是服務器,則使用 SSL_accept 代替傳統的 accept 調用
int SSL_accept(SSL *ssl);
6. 通訊結束,需要釋放前面申請的 SSL資源
int SSL_shutdown(SSL *ssl); 關閉SSL套接字;
void SSL_free (ssl); 釋放SSL套接字;
void SSL_CTX_free (ctx); 釋放SSL環境;
OpenSSL 雖然已經發展到了0.9.96版本,但是它的文檔還很少,甚至連最基本的man 函數手
冊都沒有完成。所以,本文緊緊是講述了使用OpenSSL 進行程序設計的框架。更加詳細的資
料可以參考OpenSSL 的文檔或者 Apache mod_ssl 的文檔。
通過以上的介紹,我想讀者對SSL協議已經有了一定的了解,作者有機會將會繼續給大家介紹
SSL協議的其他方面的內容。
SSL原理解密
本文出自:
http://noc.cstnet.net.cn/
范曉明
RSA公鑰加密在計算機產業中被廣泛使用在認證和加密。可以從RSA Data Security Inc.獲得的RSA公鑰加密許可證。公鑰加密是使用一對非對稱的密碼加密或解密的方法。每一對密碼由公鑰和私鑰組成。公鑰被廣泛發布。私鑰是隱密的,不 公開。用公鑰加密的數據只能夠被私鑰解密。反過來,使用私鑰加密的數據只能用公鑰解密。這個非對稱的特性使得公鑰加密很有用。
使用公鑰加密法認證
認證是一個身份認證的過程。在下列例子中包括甲和乙,公鑰加密會非常輕松地校驗身份。符號{數據} key意味著"數據"已經使用密碼加密或解密。假如甲想校驗乙的身份。乙有一對密碼,一個是公開的,另一個是私有的。乙透露給甲他的公鑰。甲產生一個隨機 信息發送給乙。甲——〉乙:random-message
乙使用他的私鑰加密消息,返回甲加密后的消息。 乙——〉甲:{random-message}乙的私鑰
甲收到這個消息然后使用乙的以前公開過的公鑰解密。他比較解密后的消息與他原先發給乙的消息。如果它們完全一致,就會知道在與乙說話。任意一個中間人不會知道乙的私鑰,也不能正確加密甲檢查的隨機消息。
除非你清楚知道你加密的消息。用私鑰加密消息,然后發送給其他人不是一個好主意。因為加密值可能被用來對付你,需要注意的是:因為只有你才有私鑰,所以只 有你才能加密消息。所以,代替加密甲發來的原始消息,乙創建了一個信息段并且加密。信息段取自隨機消息(random-message)并具有以下有用的 特性:
1. 這個信息段難以還原。任何人即使偽裝成乙,也不能從信息段中得到原始消息;
2. 假冒者將發現不同的消息計算出相同的信息段值;
3. 使用信息段,乙能夠保護自己。他計算甲發出的隨機信息段,并且加密結果,并發送加密信息段返回甲。甲能夠計算出相同的信息段并且解密乙的消息認證乙。
這個技術僅僅描繪了數字簽名。通過加密甲產生的隨機消息,乙已經在甲產生的消息簽名。因此我們的認證協議還需要一次加密。一些消息由乙產生:
甲——〉乙:你好,你是乙么?
乙——〉甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
當你使用這個協議,乙知道他發送給乙的消息,他不介意在上面簽名。他先發送不加密的信息,"甲,我是乙。",然后發送信息段加密的消息版本。甲可以非常方便地校驗乙就是乙,同時,乙還沒有在他不想要的信息上簽名。
提交公鑰
那么,乙怎樣以可信的方式提交他的公鑰呢?看看認證協議如下所示:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的公鑰
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] } 乙的私鑰
在這個協議下,任何人都能夠成為"乙"。所有你所要的只是公鑰和私鑰。你發送給甲說你就是乙,這樣你的公鑰就代替了乙的密碼。然后,你發送用你的私鑰加密的消息,證明你的身份。甲卻不能發覺你并不是乙。為了解決這個問題,標準組織已經發明了證書。一個證書有以下的內容:
* 證書的發行者姓名
* 發行證書的組織
* 標題的公鑰
* 郵戳
證書使用發行者的私鑰加密。每一個人都知道證書發行者的公鑰(這樣,每個證書的發行者擁有一個證書)。證書是一個把公鑰與姓名綁定的協議。通過使用證書技術,每一個人都可以檢查乙的證書,判斷是否被假冒。假設乙控制好他的私鑰,并且他確實是得到證書的乙,就萬事大吉了。
這些是修訂后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲, 我是乙] } 乙的私鑰
現在當甲收到乙的第一個消息,他能檢查證書,簽名(如上所述,使用信息段和公鑰解密),然后檢查標題(乙的姓名),確定是乙。他就能相信公鑰就是乙的公鑰 和要求乙證明自己的身份。乙通過上面的過程,制作一個信息段,用一個簽名版本答復甲。甲可以校驗乙的信息段通過使用從證書上得到的公鑰并檢查結果。
如果一個黑客,叫H
甲——〉H:你好
H——〉不能建立一個令甲相信的從乙的消息。
交換密碼(secret)
一旦甲已經驗證乙后,他可以發送給乙一個只有乙可以解密、閱讀的消息:
甲——〉乙:{secret}乙的公鑰
唯一找到密碼的方法只有使用乙的私鑰解碼上述的信息。交換密碼是另一個有效使用密碼加密的方法。即使在甲和乙之間的通訊被偵聽,只有乙才能得到密碼。
使用密碼作為另一個secret-key增強了網絡的安全性,但是這次這是一個對稱的加密算法(例如DES、RC4、IDE甲)。因為甲在發送給乙之前產 生了密碼,所以甲知道密碼。乙知道密碼因為乙有私鑰,能夠解密甲的信息。但他們都知道密碼,他們都能夠初始化一個對稱密碼算法,而且開始發送加密后的信 息。這兒是修定后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉乙:ok 乙,here is a secret {secret}乙的公鑰
乙——〉甲:{some message}secret-key
黑客
那么如果有一個惡意的黑客H在甲和乙中間,雖然不能發現甲和乙已經交換的密碼,但能干擾他們的交談。他可以放過大部分信息,選擇破壞一定的信息(這是非常簡單的,因為他知道甲和乙通話采用的協議)。
甲——〉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忽略一些數據不修改,直到甲和乙交換密碼。然后H干擾乙給甲的信息。在這一點上,甲相信乙,所以他可能相信已經被干擾的消息并且盡力解密。
需要注意的是,H不知道密碼,他所能做的就是毀壞使用秘鑰加密后的數據。基于協議,H可能不能產生一個有效的消息。但下一次呢?
為了阻止這種破壞,甲和乙在他們的協議中產生一個校驗碼消息(message authentication code)。一個校驗碼消息(MAC)是一部分由密碼和一些傳輸消息產生的數據。信息段算法描述的上述特性正是它們抵御H的功能:
MAC= Digest[some message,secret ]
因為H不知道密碼,他不能得出正確的值。即使H隨機干擾消息,只要數據量大,他成功的機會微乎其微。例如,使用HD5(一個RSA發明的好的加密算法), 甲和乙能夠發送128位MAC值和他們的消息。H猜測正確的MAC的幾率將近1/18,446,744,073,709,551,616約等于零。
這是又一次修改后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:嗨,我是乙,乙的校驗
甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
ok 乙,here is a secret {secret} 乙的公鑰
{some message,MAC}secret-key
現在H已經無技可施了。他干擾了得到的所有消息,但MAC計算機能夠發現他。甲和乙能夠發現偽造的MAC值并且停止交談。H不再能與乙通訊。
OpenSSL FAQ
http://www.linuxforum.net
何偉平 譯
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).
交易,這時Web頁面上需要傳輸重要或敏感的數據,例如用戶的銀行帳戶、密碼等,所以網絡安全
就成為現代計算機網絡應用急需解決的問題。
現行網上銀行和電子商務等大型的網上交易系統普遍采用HTTP和SSL相結合的方式。服務器端采用
支持SSL的Web服務器,用戶端采用支持SSL的瀏覽器實現安全通信。
SSL是Secure Socket Layer(安全套接層協議)的縮寫,可以在Internet上提供秘密性傳輸。
Netscape公司在推出第一個Web瀏覽器的同時,提出了SSL協議標準,目前已有3.0版本。SSL采用公
開密鑰技術。其目標是保證兩個應用間通信的保密性和可靠性,可在服務器端和用戶端同時實現支
持。目前,利用公開密鑰技術的SSL協議,已成為Internet上保密通訊的工業標準。本文著重在
SSL協議和SSL程序設計兩方面談談作者對SSL的理解。
SSL協議初步介紹
安全套接層協議能使用戶/服務器應用之間的通信不被攻擊者,并且始終對服務器進行認證,
還可選擇對用戶進行認證。SSL協議要求建立在可靠的傳輸層協議(TCP)之上。SSL協議的優勢在于
它是與應用層協議獨立無關的,高層的應用層協議(例如:HTTP,FTP,TELNET等)能透明地建立于
SSL協議之上。SSL協議在應用層協議通信之前就已經完成加密算法、通信密鑰的協商及服務器認證
工作。在此之后應用層協議所傳送的數據都會被加密,從而保證通信的私密性。
通過以上敘述,SSL協議提供的安全信道有以下三個特性:
1.數據的保密性
信息加密就是把明碼的輸入文件用加密算法轉換成加密的文件以實現數據的保密。加密的過程需要
用到密匙來加密數據然后再解密。沒有了密鑰,就無法解開加密的數據。數據加密之后,只有密匙
要用一個安全的方法傳送。加密過的數據可以公開地傳送。
2.數據的一致性
加密也能保證數據的一致性。例如:消息驗證碼(MAC),能夠校驗用戶提供的加密信息,接收者可
以用MAC來校驗加密數據,保證數據在傳輸過程中沒有被篡改過。
3.安全驗證
加密的另外一個用途是用來作為個人的標識,用戶的密匙可以作為他的安全驗證的標識。
SSL是利用公開密鑰的加密技術(RSA)來作為用戶端與服務器端在傳送機密資料時的加密通訊協定。
目前,大部分的Web 服務器及瀏覽器都廣泛支持SSL 技術。當瀏覽器試圖連接一個具有SSL認證加
密的服務器時,就會喚醒一個SSL會話,瀏覽器檢查認證,必須具備下面三個條件:
1)有一個權威機構發放證書,當然可以創建自我簽訂的證書(x509 結構)。
2)證書不能過期。
3)證書是屬于它所連接的服務器的。
只有全部具備了這三個條件,瀏覽器才能成功完成認證。通過這三個條件,用戶能確認其瀏覽器連接
到正確的服務器,而不是連接到一些想盜取用戶密碼等重要信息的虛假的服務器上。
在當今的電子商務中還有一項被廣泛使用的安全協議是SET協議。SET(Secure Electronic Transaction,
安全電子交易)協議是由VISA和MasterCard兩大信用卡公司于1997年5月聯合推出的規范。SET能在電
子交易環節上提供更大的信任度、更完整的交易信息、更高的安全性和更少受欺詐的可能性。SET交
易分三個階段進行:用戶向商家購物并確定支付;商家與銀行核實;銀行向商家支付貨款。每個階段都
涉及到RSA對數據加密,以及RSA數字簽名。使用SET協議,在一次交易中,要完成多次加密與解密操作,
故有很高的安全性,但SET協議比SSL協議復雜,商家和銀行都需要改造系統以實現互操作。
在Linux 下,比較流行支持SSL認證的是OpenSSL服務器。OpenSSL項目是一個合作的項目,開發一個
健壯的、商業等級的、完整的開放源代碼的工具包,用強大的加密算法來實現安全的Socket層
(Secure Sockets Layer,SSL v2/v3)和傳輸層的安全性(Transport Layer Security,TLS v1)。
這個項目是由全世界的志愿者管理和開發OpenSSL工具包和相關文檔。
如何在Linux下配置OpenSSL服務器,首先從OpenSSL的主頁(http://www.openssl.org/)上下載
openssl-version.tar.gz軟件包來編譯安裝,與Apache服務器配合可以建立支持SSL的Web服務器,
并可以使用自我簽訂的證書做認證,關于如何編譯、安裝OpenSSL服務器,可以參考一下OpenSSL HOWTO
文檔。
SSL 程序設計初步介紹
SSL 通訊模型為標準的C/S 結構,除了在 TCP 層之上進行傳輸之外,與一般的通訊沒有什么明顯的區
別。在這里,我們主要介紹如何使用OpenSSL進行安全通訊的程序設計。關于OpenSSL 的一些詳細的信
息請參考OpenSSL的官方主頁 http://www.openssl.org。
在使用OpenSSL前,必須先對OpenSSL 進行初始化,以下的三個函數任選其一:
SSL_library_init(void);
OpenSSL_add_ssl_algorithms();
SSLeay_add_ssl_algorithms();
事實上 后面的兩個函數只是第一個函數的宏。
如果要使用OpenSSL的出錯信息,使用SSL_load_error_strings (void)進行錯誤信息的初始化。以后
可以使用void ERR_print_errors_fp(FILE *fp) 打印SSL的錯誤信息。
一次SSL連接會話一般要先申請一個SSL 環境,基本的過程是:
1. SSL_METHOD* meth = TLSv1_client_method(); 創建本次會話連接所使用的協議,如果是客戶端可
以使用
SSL_METHOD* TLSv1_client_method(void); TLSv1.0 協議
SSL_METHOD* SSLv2_client_method(void); SSLv2 協議
SSL_METHOD* SSLv3_client_method(void); SSLv3 協議
SSL_METHOD* SSLv23_client_method(void); SSLv2/v3 協議
服務器同樣需要創建本次會話所使用的協議:
SSL_METHOD *TLSv1_server_method(void);
SSL_METHOD *SSLv2_server_method(void);
SSL_METHOD *SSLv3_server_method(void);
SSL_METHOD *SSLv23_server_method(void);
需要注意的是客戶端和服務器需要使用相同的協議。
2.申請SSL會話的環境 CTX,使用不同的協議進行會話,其環境也是不同的。申請SSL會話環
境的OpenSSL函數是
SSLK_CTX* SSL_CTX_new (SSL_METHOD*); 參數就是前面我們申請的 SSL通訊方式。返回當前
的SSL 連接環境的指針。
然后根據自己的需要設置CTX的屬性,典型的是設置SSL 握手階段證書的驗證方式和加載自己
的證書。
void SSL_CTX_set_verify (SSL_CTX* , int , int* (int, X509_STORE_CTX*) )
設置證書驗證的方式。
第一個參數是當前的CTX 指針,第二個是驗證方式,如果是要驗證對方的話,就使用
SSL_VERIFY_PEER。不需要的話,使用SSL_VERIFY_NONE.一般情況下,客戶端需要驗證對方,而
服務器不需要。第三個參數是處理驗證的回調函數,如果沒有特殊的需要,使用空指針就可以了。
void SSL_CTX_load_verify_locations(SSL_CTX*, const char* , const char*);
加載證書;
第一個參數同上,參數二是證書文件的名稱,參數三是證書文件的路徑;
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
加載本地的證書;type 指明證書文件的結構類型;失敗返回-1
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
加載自己的私鑰;type 參數指明私鑰文件的結構類型;失敗返回-1
加載了證書和文件之后,就可以驗證私鑰和證書是否相符:
BOOl SSL_CTX_check_private_key (SSL_CTX*);
3.既然SSL 使用TCP 協議,當然需要把SSL attach 到已經連接的套接字上了:
SSL* SSL_new (SSL_CTX*); 申請一個SSL 套節字;
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. 握手成功之后,就可以進行通訊了,使用SSL_read 和SS_write 讀寫SSL 套接字代替傳統的
read 、write
int SSL_read (SSL *ssl, char *buf, int num );
int SSL_write (SSL *ssl, char *buf, int num);
如果是服務器,則使用 SSL_accept 代替傳統的 accept 調用
int SSL_accept(SSL *ssl);
6. 通訊結束,需要釋放前面申請的 SSL資源
int SSL_shutdown(SSL *ssl); 關閉SSL套接字;
void SSL_free (ssl); 釋放SSL套接字;
void SSL_CTX_free (ctx); 釋放SSL環境;
OpenSSL 雖然已經發展到了0.9.96版本,但是它的文檔還很少,甚至連最基本的man 函數手
冊都沒有完成。所以,本文緊緊是講述了使用OpenSSL 進行程序設計的框架。更加詳細的資
料可以參考OpenSSL 的文檔或者 Apache mod_ssl 的文檔。
通過以上的介紹,我想讀者對SSL協議已經有了一定的了解,作者有機會將會繼續給大家介紹
SSL協議的其他方面的內容。
SSL原理解密
本文出自:
http://noc.cstnet.net.cn/
范曉明
RSA公鑰加密在計算機產業中被廣泛使用在認證和加密。可以從RSA Data Security Inc.獲得的RSA公鑰加密許可證。公鑰加密是使用一對非對稱的密碼加密或解密的方法。每一對密碼由公鑰和私鑰組成。公鑰被廣泛發布。私鑰是隱密的,不 公開。用公鑰加密的數據只能夠被私鑰解密。反過來,使用私鑰加密的數據只能用公鑰解密。這個非對稱的特性使得公鑰加密很有用。
使用公鑰加密法認證
認證是一個身份認證的過程。在下列例子中包括甲和乙,公鑰加密會非常輕松地校驗身份。符號{數據} key意味著"數據"已經使用密碼加密或解密。假如甲想校驗乙的身份。乙有一對密碼,一個是公開的,另一個是私有的。乙透露給甲他的公鑰。甲產生一個隨機 信息發送給乙。甲——〉乙:random-message
乙使用他的私鑰加密消息,返回甲加密后的消息。 乙——〉甲:{random-message}乙的私鑰
甲收到這個消息然后使用乙的以前公開過的公鑰解密。他比較解密后的消息與他原先發給乙的消息。如果它們完全一致,就會知道在與乙說話。任意一個中間人不會知道乙的私鑰,也不能正確加密甲檢查的隨機消息。
除非你清楚知道你加密的消息。用私鑰加密消息,然后發送給其他人不是一個好主意。因為加密值可能被用來對付你,需要注意的是:因為只有你才有私鑰,所以只 有你才能加密消息。所以,代替加密甲發來的原始消息,乙創建了一個信息段并且加密。信息段取自隨機消息(random-message)并具有以下有用的 特性:
1. 這個信息段難以還原。任何人即使偽裝成乙,也不能從信息段中得到原始消息;
2. 假冒者將發現不同的消息計算出相同的信息段值;
3. 使用信息段,乙能夠保護自己。他計算甲發出的隨機信息段,并且加密結果,并發送加密信息段返回甲。甲能夠計算出相同的信息段并且解密乙的消息認證乙。
這個技術僅僅描繪了數字簽名。通過加密甲產生的隨機消息,乙已經在甲產生的消息簽名。因此我們的認證協議還需要一次加密。一些消息由乙產生:
甲——〉乙:你好,你是乙么?
乙——〉甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
當你使用這個協議,乙知道他發送給乙的消息,他不介意在上面簽名。他先發送不加密的信息,"甲,我是乙。",然后發送信息段加密的消息版本。甲可以非常方便地校驗乙就是乙,同時,乙還沒有在他不想要的信息上簽名。
提交公鑰
那么,乙怎樣以可信的方式提交他的公鑰呢?看看認證協議如下所示:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的公鑰
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] } 乙的私鑰
在這個協議下,任何人都能夠成為"乙"。所有你所要的只是公鑰和私鑰。你發送給甲說你就是乙,這樣你的公鑰就代替了乙的密碼。然后,你發送用你的私鑰加密的消息,證明你的身份。甲卻不能發覺你并不是乙。為了解決這個問題,標準組織已經發明了證書。一個證書有以下的內容:
* 證書的發行者姓名
* 發行證書的組織
* 標題的公鑰
* 郵戳
證書使用發行者的私鑰加密。每一個人都知道證書發行者的公鑰(這樣,每個證書的發行者擁有一個證書)。證書是一個把公鑰與姓名綁定的協議。通過使用證書技術,每一個人都可以檢查乙的證書,判斷是否被假冒。假設乙控制好他的私鑰,并且他確實是得到證書的乙,就萬事大吉了。
這些是修訂后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲, 我是乙] } 乙的私鑰
現在當甲收到乙的第一個消息,他能檢查證書,簽名(如上所述,使用信息段和公鑰解密),然后檢查標題(乙的姓名),確定是乙。他就能相信公鑰就是乙的公鑰 和要求乙證明自己的身份。乙通過上面的過程,制作一個信息段,用一個簽名版本答復甲。甲可以校驗乙的信息段通過使用從證書上得到的公鑰并檢查結果。
如果一個黑客,叫H
甲——〉H:你好
H——〉不能建立一個令甲相信的從乙的消息。
交換密碼(secret)
一旦甲已經驗證乙后,他可以發送給乙一個只有乙可以解密、閱讀的消息:
甲——〉乙:{secret}乙的公鑰
唯一找到密碼的方法只有使用乙的私鑰解碼上述的信息。交換密碼是另一個有效使用密碼加密的方法。即使在甲和乙之間的通訊被偵聽,只有乙才能得到密碼。
使用密碼作為另一個secret-key增強了網絡的安全性,但是這次這是一個對稱的加密算法(例如DES、RC4、IDE甲)。因為甲在發送給乙之前產 生了密碼,所以甲知道密碼。乙知道密碼因為乙有私鑰,能夠解密甲的信息。但他們都知道密碼,他們都能夠初始化一個對稱密碼算法,而且開始發送加密后的信 息。這兒是修定后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:甲,我是乙 {信息段[甲,我是乙] }乙的私鑰
甲——〉乙:ok 乙,here is a secret {secret}乙的公鑰
乙——〉甲:{some message}secret-key
黑客
那么如果有一個惡意的黑客H在甲和乙中間,雖然不能發現甲和乙已經交換的密碼,但能干擾他們的交談。他可以放過大部分信息,選擇破壞一定的信息(這是非常簡單的,因為他知道甲和乙通話采用的協議)。
甲——〉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忽略一些數據不修改,直到甲和乙交換密碼。然后H干擾乙給甲的信息。在這一點上,甲相信乙,所以他可能相信已經被干擾的消息并且盡力解密。
需要注意的是,H不知道密碼,他所能做的就是毀壞使用秘鑰加密后的數據。基于協議,H可能不能產生一個有效的消息。但下一次呢?
為了阻止這種破壞,甲和乙在他們的協議中產生一個校驗碼消息(message authentication code)。一個校驗碼消息(MAC)是一部分由密碼和一些傳輸消息產生的數據。信息段算法描述的上述特性正是它們抵御H的功能:
MAC= Digest[some message,secret ]
因為H不知道密碼,他不能得出正確的值。即使H隨機干擾消息,只要數據量大,他成功的機會微乎其微。例如,使用HD5(一個RSA發明的好的加密算法), 甲和乙能夠發送128位MAC值和他們的消息。H猜測正確的MAC的幾率將近1/18,446,744,073,709,551,616約等于零。
這是又一次修改后的協議:
甲——〉乙:你好
乙——〉甲:嗨,我是乙,乙的校驗
甲——〉乙:prove it
乙——〉甲:嗨,我是乙,乙的校驗
甲,我是乙
{信息段[甲,我是乙] } 乙的私鑰
ok 乙,here is a secret {secret} 乙的公鑰
{some message,MAC}secret-key
現在H已經無技可施了。他干擾了得到的所有消息,但MAC計算機能夠發現他。甲和乙能夠發現偽造的MAC值并且停止交談。H不再能與乙通訊。
OpenSSL FAQ
http://www.linuxforum.net
何偉平 譯
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).
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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