邱俊源, 張 躍
(清華大學(xué)深圳研究生院嵌入式系統(tǒng)與技術(shù)實(shí)驗(yàn)室,廣東深圳518055)
網(wǎng)絡(luò)通信模塊是許多數(shù)據(jù)交互系統(tǒng)的基礎(chǔ),然而在當(dāng)前嚴(yán)峻的網(wǎng)絡(luò)環(huán)境之下,網(wǎng)絡(luò)數(shù)據(jù)傳輸時常面臨著數(shù)據(jù)竊取、數(shù)據(jù)篡改以及惡意連接的威脅。按照一般的明文傳輸方法,隱私數(shù)據(jù)的保密性無法得到保證,甚至數(shù)據(jù)通訊過程都有可能遭到破壞。
遠(yuǎn)程無線多生理參數(shù)實(shí)時監(jiān)測與分析網(wǎng)絡(luò)平臺[1-2]是遠(yuǎn)程監(jiān)護(hù)和家庭護(hù)理的一個應(yīng)用,是集以心電信號為主的多生理參數(shù)采集、數(shù)據(jù)遠(yuǎn)程傳輸、監(jiān)控分析于一體的軟硬件整體解決方案。為了保障各個實(shí)時監(jiān)護(hù)服務(wù)器的監(jiān)護(hù)數(shù)據(jù)匯總到信息中心數(shù)據(jù)庫過程中的通訊安全,本文在 OpenSSL庫及WSAAsyncSelect模型基礎(chǔ)上設(shè)計并實(shí)現(xiàn)了一個基于異步消息通知及SSL安全連接協(xié)議的安全通信模塊,提出了通過面向?qū)ο蟮姆绞讲⑿刑幚戆踩W(wǎng)絡(luò)通訊的新方法,有效地解決了上述問題。
1.1.1 一般通信I/O模式及存在問題
現(xiàn)有的安全通信模塊中,基本都是基于阻塞模型,其優(yōu)勢在于簡單直接,適用于簡單應(yīng)用程序的快速原型化。采用這種模型的應(yīng)用程序,在處理I/O時往往對每個連接都要建立一至兩個線程,在線程中循環(huán)發(fā)出阻塞調(diào)用。這也正是這種模型的局限之處,創(chuàng)建多線程通常需要耗費(fèi)較多的系統(tǒng)資源,同時如果涉及到多線程數(shù)據(jù)交互更是需要進(jìn)行繁瑣的同步工作,異步通知模型則可以高效解決這種情況下的并行處理問題。
1.1.2 WSAAsyncselect模型
WSAAsyncSelect(異步選擇)模型是Winsock提供的一個有用的異步I/O模型,通過這個模型應(yīng)用程序可以接收制定套接字上的網(wǎng)絡(luò)事件通知,這些異步通知通過窗口消息的方式傳遞。要使用WSAAsyncSelect模型,須創(chuàng)建一個消息接收窗口,通過WSAAsyncSelect函數(shù)打開指定套接字上的消息通知。該函數(shù)定義如下:
常用網(wǎng)絡(luò)事件類型如表1所示。
表1 常用網(wǎng)絡(luò)事件
通過對相應(yīng)消息的處理,應(yīng)用程序即可實(shí)現(xiàn)對網(wǎng)絡(luò)連接的控制,最突出的一方面是它可以在系統(tǒng)開銷不大的情況下同時處理許多連接。通過 WSAAsyncSelect模型作為事件驅(qū)動,安全通信模塊可以進(jìn)行應(yīng)用層協(xié)議的處理,并按需調(diào)用用戶的事件處理函數(shù)。
按照功能定位的不同,與安全通信模塊有關(guān)的共3個層次,分別為發(fā)出網(wǎng)絡(luò)I/O事件的內(nèi)核層、進(jìn)行SSL協(xié)議處理的安全連接層及進(jìn)行SSL I/O事件處理的用戶邏輯層。圖1為安全通信模塊的類結(jié)構(gòu)UML定義。CAsyncSocket及CAsync-SSLSocket組成了安全連接層,CUserSocket即為實(shí)現(xiàn)用戶自定義I/O處理的用戶層。
圖1 類設(shè)計
CAsyncSocket封裝了網(wǎng)絡(luò)套接字 SOCKET變量,通過WSAAsyncSelect函數(shù)打開封裝套接字的網(wǎng)絡(luò)消息通知,并建立了對應(yīng)的隱藏窗口接收網(wǎng)絡(luò)消息,通過窗口消息處理函數(shù)構(gòu)建了網(wǎng)絡(luò)事件多路分解及調(diào)度框架。CAsyncSocket定義了對應(yīng)各網(wǎng)絡(luò)事件的處理接口,子類通過覆蓋CAsyncSocket中的OnReceive等幾個方法實(shí)現(xiàn)具體的事件處理。這項技術(shù)通過C++中的多態(tài)機(jī)制完成。
圖2 事件處理流程
CAsyncSSLSocket是整個安全通信模塊的核心,它通過繼承CAsyncSocket實(shí)現(xiàn)對套接字I/O事件的處理,在這基礎(chǔ)上通過封裝了OPENSSL庫中的SSL連接對象在套接字層上建立了SSL安全連接層,在這個類中完成了SSL連接的握手、用戶明文數(shù)據(jù)至密文的轉(zhuǎn)化及接收密文到用戶明文的轉(zhuǎn)化。
CAsyncSSLSocket中主要定義了兩類接口,一是基本I/O接口,由用戶或子類直接調(diào)用,另外就是SSL層I/O事件處理接口,這類接口需要用戶通過繼承CAsyncSSLSocket并覆蓋該類接口實(shí)現(xiàn)自己的I/O事件處理方法,其中基本接口如下:
(1)SSL連接對象創(chuàng)建接口
(2)SSL發(fā)起連接接口
(3)關(guān)聯(lián)SOCKET對象接口
(4)設(shè)置SSL連接對象為服務(wù)態(tài)接口
(5)設(shè)置SSL環(huán)境參數(shù)接口
SSL層I/O事件處理接口的設(shè)計與底層I/O事件處理接口設(shè)計是一致的,遵循高可擴(kuò)展性的原則,各個接口如下:
(1)SSL連接建立結(jié)果通知事件接口(2)SSL連接數(shù)據(jù)可讀事件處理接口
(3)SSL連接數(shù)據(jù)可發(fā)送事件處理接口
(4)SSL連接斷開事件處理接口
CUserSocket類即用戶自定義對象,通過覆蓋父類中的SSL層I/O事件處理接口完成自定義的事務(wù)邏輯處理。用戶只需調(diào)用CAsyncSSLSocket的I/O接口即可在SSL連接上進(jìn)行數(shù)據(jù)通訊,SSL層的處理對用戶來說是完全透明的,使用方法也與普通套接字風(fēng)格一致,具有較高的易用性。
整個安全通信過程中的事件處理流程如圖2所示。如前面所述,整個異步通信由內(nèi)核的底層網(wǎng)絡(luò)事件消息驅(qū)動。
首先是FD_CONNECT事件,指示套接字連接建立完成結(jié)果,如果建立完成則SSL連接層首先進(jìn)行SSL連接對象的初始化,如果是客戶端則要首先發(fā)起與服務(wù)端的SSL連接握手。
接著是不定次數(shù)的FD_READ及FD_SEND事件,在SSL連接握手未完成的情況下,SSL層首先進(jìn)行SSL握手處理,主要內(nèi)容為客戶端與服務(wù)端的證書交換、合法性驗(yàn)證及后續(xù)通訊過程的密鑰協(xié)商。完成連接握手后SSL連接進(jìn)入正常通信狀態(tài),F(xiàn)D_READ及FD_SEND事件就指示SSL層數(shù)據(jù)可讀及數(shù)據(jù)可寫,由SSL層分別調(diào)用用戶定義的SSL層I/O事件處理接口進(jìn)行處理。
最后就是套接字連接中斷事件,SSL層首先進(jìn)行已分配的SSL連接對象的回收處理,最后調(diào)用用戶的SSL連接中斷處理接口。
SSL協(xié)議全稱為SecureSocketLayer協(xié)議,最早由Netscape公司提出,它位于傳輸層協(xié)議與應(yīng)用層協(xié)議間,用以提供安全通信保障。SSL中又包含兩個協(xié)議:SSLRecordProtocol及SSL Handshake Protocol,前者可以對不同的上層應(yīng)用協(xié)議進(jìn)行封裝,后者則為在SSLRecordProtocol之上的SSL連接握手協(xié)議,在連接開始前進(jìn)行連接雙方的身份驗(yàn)證并協(xié)商好后續(xù)連接使用的加密算法及密鑰。
SSL協(xié)議提供以下特性:
(1)身份驗(yàn)證,連接端的身份通過非對稱加密算法進(jìn)行驗(yàn)證。
(2)數(shù)據(jù)保密性,連接雙方通過握手協(xié)商的對稱加密算法及密鑰保障連接過程的數(shù)據(jù)不被竊聽。
(3)數(shù)據(jù)完整性,通過在數(shù)據(jù)包上附加數(shù)字摘要,通過MD5,SHA1等安全摘要算法計算得到,可保障數(shù)據(jù)包不被篡改。
當(dāng)前SSL協(xié)議已經(jīng)有諸多版本:SSL1.0、SSL2.0、SSL3.0及TLS1.2等等,后兩者是最常用的版本。
SSL握手主要進(jìn)行連接雙方的身份驗(yàn)證及密鑰協(xié)商,其過程如圖3所示。
握手過程首先由客戶端的發(fā)起,ClientHello及ServerHello組成了握手的第一個階段,完成兩端隨機(jī)數(shù)的交換,確定加密算法套件及壓縮算法。
圖3 SSL握手協(xié)議[3-4]
第二階段是證書驗(yàn)證階段,客戶端與服務(wù)器通過Certificate報文交換數(shù)字證書,完成相互驗(yàn)證。其次完成密鑰參數(shù)協(xié)商,在服務(wù)端證書中不包含用于協(xié)商的密鑰信息時還需通過ServerKeyExchange發(fā)送相應(yīng)的密鑰,其內(nèi)容根據(jù)密鑰產(chǎn)生算法而不同,如使用RSA公鑰算法就包含服務(wù)端的公鑰,而DH算法則為服務(wù)端的DH公開參數(shù)。
第三階段客戶端及服務(wù)端將協(xié)商出后續(xù)通訊所使用的密鑰??蛻舳耸紫韧ㄟ^隨機(jī)數(shù)產(chǎn)生一個預(yù)主密鑰(Pre master secret)通過ClientKeyExchange將用服務(wù)端公鑰加密的預(yù)主密鑰發(fā)送給服務(wù)端。雙方將通過預(yù)主密鑰及Hello階段交換的服務(wù)端及客戶端產(chǎn)生的隨機(jī)數(shù)產(chǎn)生相同主密鑰(master secret),隨后就可以根據(jù)主密鑰生成加密及計算消息驗(yàn)證碼用的密鑰參數(shù)。
最后,雙方在主密鑰協(xié)商結(jié)束后,將分別發(fā)送一個change cipherspec消息,這是位于SSLRecordLayer的報文,表示接下來所發(fā)送的所有數(shù)據(jù)都要使用協(xié)商的加密算法及密鑰進(jìn)行加密處理。緊接著發(fā)送Finished報文,其內(nèi)容為開始以來所有握手?jǐn)?shù)據(jù)的散列碼,通過協(xié)商的算法及密鑰加密。以此檢驗(yàn)密鑰交換及身份驗(yàn)證處理都已成功完成。至此,握手過程結(jié)束,應(yīng)用層數(shù)據(jù)交換就可以開始了。
通過OpenSSL進(jìn)行SSL連接主要需要兩個對象,SSL_CTX及SSL對象,前者即SSL上下文,進(jìn)行SSL連接參數(shù)的設(shè)定,后者即實(shí)際處理SSL連接的對象。建立SSL對象及綁定套接字的語句主要如下:
SSL*ssl_=SSL_new(sslctx_);
SSL_set_fd(ssl_,m_hSocket);
sslctx_即用戶建立的SSL上下文,m_hSocket則為需要綁定的套接字連接,經(jīng)過綁定后套接字的I/O模式阻塞與否將使SSL對象具有相同的I/O模式,后續(xù)一系列函數(shù)都需要按照非阻塞的模式進(jìn)行處理。
握手過程主要通過SSL_set_connect_state/SSL_set_accept_state配合SSL_do_handshake完成。前者指定連接角色,后者通過若干次調(diào)用完成具體握手工作。
SSL中應(yīng)用層數(shù)據(jù)通過SSL RecordLayer協(xié)議進(jìn)行傳輸,可提供數(shù)據(jù)壓縮及數(shù)據(jù)保護(hù)(數(shù)據(jù)保密性及數(shù)據(jù)完整性),使用的壓縮算法和數(shù)據(jù)加密算法及密鑰均在握手過程中協(xié)商得到。
數(shù)據(jù)保密性通過加密算法實(shí)現(xiàn),為了保證數(shù)據(jù)處理速度,SSL使用的是對稱加密算法,即給定一個明文一個密鑰,加密生成的密文長度與明文一致,加解密使用相同的密鑰。比較常用的加密算法有DES、3DES(三重DES加密)、RC4及目前安全性較高的AES(高級加密標(biāo)準(zhǔn))。經(jīng)過加密處理后即使密文被中途竊取,如果沒有密鑰就無法獲得實(shí)際內(nèi)容,而SSL的密鑰是每個會話通過握手協(xié)商的獨(dú)立的密鑰,進(jìn)一步提高了破譯密鑰的難度。
數(shù)據(jù)完整性則是通過消息鑒別碼 (message authentication code,又稱密碼校驗(yàn)和)實(shí)現(xiàn)的,消息鑒別碼即按照公開的算法及協(xié)商的密鑰根據(jù)輸入數(shù)據(jù)產(chǎn)生一個固定長度的摘要數(shù)據(jù)。特點(diǎn)是輸入數(shù)據(jù)有微小的變化就會導(dǎo)致摘要數(shù)據(jù)出現(xiàn)劇烈變化,而且不同輸入數(shù)據(jù)產(chǎn)生同樣的摘要數(shù)據(jù)概率是十分低以致可以忽略不計?;谡惴ǖ奶攸c(diǎn),接收端只要按照同樣的算法及密鑰對數(shù)據(jù)重新生成MAC數(shù)據(jù)檢驗(yàn)與接收到的MAC數(shù)據(jù)是否一致就可以判斷消息是否完整,有效防止了數(shù)據(jù)篡改。同時由于SSL計算MAC時同時使用了應(yīng)用層數(shù)據(jù)及每個數(shù)據(jù)包的序列號,可有效抵御基于數(shù)據(jù)包序打亂的攻擊。
OpenSSL中對SSL連接的數(shù)據(jù)讀寫通過SSL_read及SSL_write函數(shù)實(shí)現(xiàn),兩個接口聲明如下:
int SSL_read(SSL*ssl,void*buf,int num);
int SSL_write(SSL*ssl,const void*buf,int num);
在CAsyncSSLSocket中通過SSLRecv及SSLSend封裝了應(yīng)用層數(shù)據(jù)讀寫的接口,對用戶隱藏了使用OpenSSL庫函數(shù)的細(xì)節(jié)。
使用 OpenSSL需要鏈接到指定庫,win32平臺下為libeay32.lib及ssleay32.lib,輔助類CUseOpenSSL實(shí)現(xiàn)了庫的初始化及清理工作及多線程環(huán)境初始化。
SSL連接參數(shù)設(shè)置通過SSL_CTX完成,它指定了SSL連接使用的協(xié)議版本,握手過程中的驗(yàn)證模式,及進(jìn)行密鑰交換及身份驗(yàn)證所必要的用戶證書、用戶私鑰、CA證書。一般在程序開始時建立SSL_CTX對象,在程序結(jié)束時刪除。在CUse-OpenSSL中設(shè)計了創(chuàng)建 SSL_CTX對象的靜態(tài)方法 Create-SSLCTX()。
創(chuàng)建SSL上下文的具體步驟及關(guān)鍵函數(shù)如表2所示。
表2 SSL_CTX創(chuàng)建
數(shù)字證書是SSL連接中重要組成部分,通過構(gòu)建自己的CA系統(tǒng)就可以創(chuàng)建內(nèi)部專用的SSL連接。證書的生成可以通過OpenSSL的實(shí)用程序完成[5],這里就不贅述了。
示例通信程序在VS2005環(huán)境下實(shí)現(xiàn),通過以下功能進(jìn)行模塊測試:客戶端與服務(wù)端間同時建立多個SSL連接,每個連接中客戶端發(fā)送1MB的數(shù)據(jù)至服務(wù)端,服務(wù)端接收完畢后返回應(yīng)答文本。應(yīng)用層協(xié)議處理通過繼承自 CAsyncSSLSocket的用戶類實(shí)現(xiàn),對應(yīng)服務(wù)端及客戶端分別為 CServer及CClient。要建立多個連接用戶僅需要構(gòu)建多個CAsyncSSLSocket類的實(shí)例。使用上述模塊進(jìn)行通訊的流程如圖4所示。
100Mbps局域網(wǎng)帶寬條件下同時建立5個連接的測試結(jié)果如圖5、圖6所示,每個連接使用的SSL協(xié)議版本均為SSLv3,數(shù)據(jù)加密使用AES256位加密算法,摘要算法使用SHA。
圖4 通訊流程
圖5 測試結(jié)果-服務(wù)端
圖6 測試結(jié)果-客戶端
表3列出了一些典型帶寬及連接數(shù)條件下的測試結(jié)果,測試環(huán)境為WindowsXPsp2、奔騰41.5GHzCPU、1G內(nèi)存。測試表明上述模塊能通過單線程并行處理多個安全網(wǎng)絡(luò)連接,避免了線程切換及同步開銷,具備較高的并行處理性能,隨著連接數(shù)增加,總的數(shù)據(jù)傳輸速率僅略微下降。高帶寬條件下,數(shù)據(jù)的加密及完整性處理一定程度降低了傳輸速度,但在普通帶寬條件下,則是網(wǎng)絡(luò)帶寬構(gòu)成了性能瓶頸。示例也表明通過用面向?qū)ο蟮姆绞竭M(jìn)行安全網(wǎng)絡(luò)連接的處理,用戶僅需關(guān)注具體的事務(wù)邏輯,可以有效簡化安全通訊系統(tǒng)的構(gòu)建。
表3 測試結(jié)果
本文結(jié)合WSAAsyncSelect套接字I/O模型及SSL協(xié)議設(shè)計并實(shí)現(xiàn)了一個異步消息模型驅(qū)動的安全通信模塊。多層設(shè)計、多態(tài)方法的應(yīng)用,將用戶的應(yīng)用層協(xié)議設(shè)計實(shí)現(xiàn)與安全連接基礎(chǔ)功能的實(shí)現(xiàn)進(jìn)行了有效地隔離,使通信模塊具有了較高的可擴(kuò)展性。SSL協(xié)議的應(yīng)用,則使用戶的通訊數(shù)據(jù)在數(shù)據(jù)保密性、數(shù)據(jù)完整性上都得到了較高的保證。基于消息循環(huán)的事件處理模型更是讓該模塊具備了在一個線程中同時管理多個安全連接的功能,同時也能與使用Windows界面的應(yīng)用程序進(jìn)行無縫結(jié)合。
該模塊主要是面向幾十?dāng)?shù)量級連接數(shù)下的通訊應(yīng)用,對需要進(jìn)行成千上萬連接處理的需要高伸縮性的應(yīng)用還需通過完成端口等其他I/O模型。目前該安全通信模塊已經(jīng)在多生理參數(shù)監(jiān)護(hù)數(shù)據(jù)匯總系統(tǒng)中得到了應(yīng)用,取得了較好的效果。
[1]張和君,張躍,周炳坤.遠(yuǎn)程心電監(jiān)護(hù)軟件系統(tǒng)的設(shè)計與實(shí)現(xiàn)[J].計算機(jī)工程與應(yīng)用,2005,41(12):219-224.
[2]周炳坤,張躍,徐廷松.遠(yuǎn)程多生理參數(shù)監(jiān)護(hù)系統(tǒng)通信協(xié)議的研究[J].計算機(jī)工程,2008,34(18):102-104.
[3]RFC 5246,Thetransportlayersecurity(TLS)protocolversion1.2[S].
[4]RFC 4366,transport layer security(TLS)extensions[S].
[5]王志海,童新海,沈寒輝.OpenSSL與網(wǎng)絡(luò)信息安全——基礎(chǔ)、結(jié)構(gòu)和指令[M].北京:清華大學(xué)出版社,北京交通大學(xué)出版社,2007.
[6]孫海民.精通WindowsSockets網(wǎng)絡(luò)開發(fā):基于VisualC++實(shí)現(xiàn)[M].北京:人民郵電出版社,2008.
[7]鄧志宏,顏君彪.基于PKI的網(wǎng)絡(luò)信息安全模型的研究與設(shè)計[J].計算機(jī)工程與設(shè)計,2007,28(2):349-350.
[8]王宇,盧昱.信息網(wǎng)絡(luò)的通信安全控制[J].計算機(jī)工程,2006,32(12):173-175.