SSL協議的分析及實現
1 引言 SSL是一種在客戶端和 服務器 端之間建立安全通道的協議。SSL一經提出,就在Internet上得到廣泛的應用。SSL最常用來保護Web的安全。為了保護存有敏感信息Web的服務器的安全,消除用戶在Internet上數據傳輸的安全顧慮。 OpenSSL是一個支持SSL認證的服務
1引言
SSL是一種在客戶端和
服務器端之間建立
安全通道的協議。SSL一經提出,就在Internet上得到廣泛的應用。SSL最常用來保護
Web的
安全。為了保護存有敏感信息
Web的
服務器的安全,消除用戶在Internet上數據傳輸的安全顧慮。
OpenSSL是一個支持SSL認證的服務器.它是一個源碼開放的自由軟件,支持多種操作系統。OpenSSL軟件的目的是實現一個完整的、健壯的、商業級的開放源碼工具,通過強大的加密算法來實現建立在傳輸層之上的安全性。OpenSSL包含一套SSL協議的完整接口,應用程序應用它們可以很方便的建立起安全套接層,進而能夠通過網絡進行安全的數據傳輸。
2 SSL協議概述
SSL 是Secure socket Layer英文縮寫,它的中文意思是安全套接層協議,指使用公鑰和私鑰技術組合的安全網絡通訊協議。SSL協議是網景公司(Netscape)推出的基于 WEB應用的安全協議,SSL協議指定了一種在應用程序協議(如Http、Telenet、NMTP和FTP等)和TCP/IP協議之間提供數據安全性分層的機制,它為TCP/IP連接提供數據加密、服務器認證、消息完整性以及可選的客戶機認證,主要用于提高應用程序之間數據的安全性,對傳送的數據進行加密和隱藏,確保數據在傳送中不被改變,即確保數據的完整性。
SSL 以對稱密碼技術和公開密碼技術相結合,可以實現如下三個通信目標:
(1)秘密性: SSL客戶機和服務器之間傳送的數據都經過了加密處理,網絡中的非法竊聽者所獲取的信息都將是無意義的密文信息。
( 2)完整性: SSL利用密碼算法和散列(HASH)函數,通過對傳輸信息特征值的提取來保證信息的完整性,確保要傳輸
的信息全部到達目的地,可以避免服務器和客戶機之間的信息受到破壞。
(3)認證性:利用證書技術和可信的第三方認證,可以讓客戶機和服務器相互識別對方的身份。為了驗證證書持有者是其合法用戶(而不是冒名用戶), SSL要求證書持有者在握手時相互交換數字證書,通過驗證來保證對方身份的合法性。
3 SSL協議的體系結構
SSL協議位于TCP/IP協議模型的網絡層和應用層之間,使用TCP來提供一種可靠的端到端的安全服務,它是客戶/服務器應用之間的通信不被攻擊竊聽,并且始終對服務器進行認證,還可以選擇對客戶進行認證。SSL協議在應用層通信之前就已經完成加密算法、通信密鑰的協商以及服務器認證
javascript:tagshow(event, '%B9%A4%D7%F7');" href="javascript:;" target=_self>
工作,在此之后,應用層協議所傳送的數據都被加密。SSL實際上是共同工作的兩層協議組成,如圖1所示。從體系結構圖可以看出SSL安全協議實際是SSL握手協議、SSL修改密文協議、SSL警告協議和SSL記錄協議組成的一個協議族。
握手
協議 |
修改密
文協議 |
報警
協議 |
SSL記錄協議 |
TCP |
IP |
圖1 SSL體系結構
SSL記錄協議為SSL連接提供了兩種服務:一是機密性,二是消息完整性。為了實現這兩種服務, SSL記錄協議對接收的數據和被接收的數據工作過程是如何實現的呢? SSL記錄協議接收傳輸的應用報文,將數據分片成可管理的塊,進行數據壓縮(可選),應用MAC,接著利用IDEA、DES、3DES或
其他加密算法進行數據加密,最后增加由內容類型、主要版本、次要版本和壓縮長度組成的首部。被接收的數據剛好與接收數據工作過程相反,依次被解密、驗證、解壓縮和重新裝配,然后交給更高級用戶。
SSL修改密文協議是使用SSL記錄協議服務的SSL高層協議的3個特定協議之一,也是其中最簡單的一個。協議由單個消息組成,該消息只包含一個值為1的單個字節。該消息的唯一作用就是使未決狀態拷貝為當前狀態,更新用于當前連接的密碼組。為了保障SSL傳輸過程的安全性,雙方應該每隔一段時間改變加密規范。
SSL告警協議是用來為對等實體傳遞SSL的相關警告。如果在通信過程中某一方發現任何異常,就需要給對方發送一條警示消息通告。警示消息有兩種:一種是 Fatal錯誤,如傳遞數據過程中,發現錯誤的MAC,雙方就需要立即中斷會話,同時消除自己緩沖區相應的會話記錄;第二種是Warning消息,這種情況,通信雙方通常都只是記錄
日志,而對通信過程不造成任何影響。SSL握手協議可以使得服務器和客戶能夠相互鑒別對方,協商具體的加密算法和MAC算法以及保密密鑰,用來保護在SSL記錄中發送的數據。
SSL握手協議允許通信實體在交換應用數據之前協商密鑰的算法、加密密鑰和對客戶端進行認證(可選)的協議,為下一步記錄協議要使用的密鑰信息進行協商,使客戶端和服務器建立并保持安全通信的狀態信息。SSL握手協議是在任何應用程序數據傳輸之前使用的。SSL握手協議包含四個階段:第一個階段建立安全能力;第二個階段服務器鑒別和密鑰交換;第三個階段客戶鑒別和密鑰交換;第四個階段完成握手協議。
4 SSL協議的實現
基于OpenSSL的程序可以被分為兩個部分:客戶機和服務器,使用SSL協議使通信雙方可以相互驗證對方身份的真實性,并且能夠保證數據的完整性和機密性。建立SSL通信的過程如圖2所示。
圖2 SSL通信過程
SSL通信模型采用標準的C/S結構,除了在TCP層上進行傳輸之外,與普通的網絡通信協議沒有太大的區別,基于OpenSSL的程序都要遵循以下幾個步驟:
(1 ) OpenSSL初始化
在使用OpenSSL之前,必須進行相應的協議初始化工作,這可以通過下面的函數實現:
int SSL_library_int(void);
(2 ) 選擇會話協議
在利用OpenSSL開始SSL會話之前,需要為客戶端和服務器制定本次會話采用的協議,目前能夠使用的協議包括TLSv1.0、SSLv2、SSLv3、SSLv2/v3。
需要注意的是,客戶端和服務器必須使用相互兼容的協議,否則SSL會話將無法正常進行。
(3 ) 創建會話環境
在OpenSSL中創建的SSL會話環境稱為CTX,使用不同的協議會話,其環境也
不一樣的。申請SSL會話環境的OpenSSL函數是:
SSL_CTX *SSL_CTX_new(SSL_METHOD * method);
當SSL會話環境申請成功后,還要根據實際的需要設置CTX的屬性,通常的設置是指定SSL握手階段證書的驗證方式和加載自己的證書。制定證書驗證方式的函數是:
int SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int(*verify_callback),int(X509_STORE_CTX *));
為SSL會話環境加載CA證書的函數是:
SSL_CTX_load_verify_location(SSL_CTX *ctx,const char *Cafile,const char *Capath);
為SSL會話加載用戶證書的函數是:
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,int type);
為SSL會話加載用戶私鑰的函數是:
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx,const char* file,int type);
在將證書和私鑰加載到SSL會話環境之后,就可以調用下面的函數來驗證私鑰和證書是否相符:
int SSL_CTX_check_private_key(SSL_CTX *ctx);
(4) 建立SSL套接字
SSL套接字是建立在普通的TCP套接字基礎之上,在建立SSL套接字時可以使用下面的一些函數:
SSL *SSl_new(SSL_CTX *ctx);
//申請一個SSL套接字
int SSL_set_fd(SSL *ssl,int fd);)
//綁定讀寫套接字
int SSL_set_rfd(SSL *ssl,int fd);
//綁定只讀套接字
int SSL_set_wfd(SSL *ssl,int fd);
//綁定只寫套接字
(5) 完成SSL握手
在成功創建SSL套接字后,客戶端應使用函數SSL_connect( )替代傳統的函數connect( )來完成握手過程:
int SSL_connect(SSL *ssl);
而對服務器來講,則應使用函數SSL_ a
clearcase/" target="_blank" >ccept ( )替代傳統的函數accept ( )來完成握手過程:
int SSL_accept(SSL *ssl);
握手過程完成之后,通常需要詢問通信雙方的證書信息,以便進行相應的驗證,這可以借助于下面的函數來實現:
X509 *SSL_get_peer_certificate(SSL *ssl);
該函數可以從SSL套接字中提取對方的證書信息,這些信息已經被SSL驗證過了。
X509_NAME *X509_get_subject_name(X509 *a);
該函數得到證書所用者的名字。
(6) 進行數據傳輸
當SSL握手完成之后,就可以進行安全的數據傳輸了,在數據傳輸階段,需要使用SSL_read( )和SSL_write( )來替代傳統的read( )和write( )函數,來完成對套接字的讀寫操作:
int SSL_read(SSL *ssl,void *buf,int num);
int SSL_write(SSL *ssl,const void *buf,int num);
(7 ) 結束SSL通信
當客戶端和服務器之間的數據通信完成之后,調用下面的函數來釋放已經申請的SSL資源:
int SSL_shu
tdown(SSL *ssl);
//關閉SSL套接字
void SSl_free(SSL *ssl);
//釋放SSL套接字
void SSL_CTX_free(SSL_CTX *ctx);
//釋放SSL會話環境
4 結束語
SSL協議采用數字證書進行雙端實體認證,用非對稱加密算法進行密鑰協商,用對稱加密算法將數據加密后進行傳輸以保證數據的保密性,并且通過計算數字摘要來驗證數據在傳輸過程中是否被篡改和偽造,從而為敏感數據在Internet上的傳輸提供了一種安全保障手段。
OpenSSL是一個開放源代碼的SSL協議的產品實現,它采用C語言作為
開發語言,具備了跨系統的
性能。調用OpenSSL 的函數就可以實現一個SSL加密的安全數據傳輸通道,從而保護客戶端和服務器之間數據的安全。
參考文獻
[1] 信息系統安全[M].戴宗坤,羅萬伯 北京:電子工業出版社,2002
[2] 計算機
網絡安全與加密技術[M]. 李海泉,李健.北京:科學出版社,2001
[3] SSL與TLS Designing and Building Secure Systems.北京:中國電力出版社,2002
[4] Network Security with Openss1.
Publisher:O’Reilly& Associates.2002
原文轉自:http://www.anti-gravitydesign.com