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