linux openssl基礎介紹
來源:互聯網
上載者:User
現行網上銀行和電子商務等大型的網上交易系統普遍採用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的首頁()上下載openssl-version.tar.gz軟體包來編譯安裝,與Apache伺服器配合可以建立支援SSL的Web伺服器,並可以使用自我簽訂的認證做認證,關於如何編譯、安裝OpenSSL伺服器,可以參考一下OpenSSL HOWTO文檔。
SSL 程式設計初步介紹
SSL 通訊模型為標準的C/S 結構,除了在 TCP 層之上進行傳輸之外,與一般的通訊沒有什麼明顯的區別。在這裡,我們主要介紹如何使用OpenSSL進行安全通訊的程式設計。關於OpenSSL 的一些詳細的資訊請參考OpenSSL的官方首頁 。
在使用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.一般情況下,用戶端需要驗證對方,而伺服器不需要。第三個參數是處理驗證的回呼函數,如果沒有特殊的需要,使用null 指標就可以了。
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協議的其他方面的內容。
(作者:張雲帆)