辛 陽,王眾全,臧家義*
1.齊魯工業(yè)大學(xué)(山東省科學(xué)院) 電氣工程與自動化學(xué)院,濟南 250353 2.山東安控信息科技有限公司,濟南 250101
為了安全、經(jīng)濟、可靠的發(fā)供電,合理地分配電能,保證電力質(zhì)量指標(biāo),及時地處理和防止系統(tǒng)事故,配電自動化系統(tǒng)應(yīng)集中管理、統(tǒng)一調(diào)度,建立與之相適應(yīng)的通信系統(tǒng)[1]。因此配電自動化系統(tǒng)的通信安全是目前主要研究方向,是實現(xiàn)電網(wǎng)上下級之間信息交互的重要手段,為電網(wǎng)正常運行、電網(wǎng)的維修等提供技術(shù)支撐。通過建立安全防護體系,使用防火墻、物理隔離、主機防護等安全防護技術(shù)和管理措施來保護電網(wǎng)系統(tǒng)的安全[2]。
電力加密機的使用可有效確保電力系統(tǒng)的通信安全[3]。加密技術(shù)是指將原始數(shù)據(jù)通過編碼的方式轉(zhuǎn)變?yōu)槊芪暮桶丫幋a后的密文解碼為原始數(shù)據(jù)的技術(shù),其中,解碼是編碼的逆過程[4]。對稱和非對稱密鑰算法是兩種不同的加密類型。對稱加密算法是使用最多的一個,因為它的實現(xiàn)簡單,所以應(yīng)用比較廣泛,并且是目前大家較為認可的技術(shù)。對稱加密過程可以概括為數(shù)據(jù)發(fā)送方將原始數(shù)據(jù)使用對稱密鑰并經(jīng)過加密算法處理后得到密文的這樣一個流程,而解密方只需使用加密算法的逆算法和使用對稱密鑰進行解密,就可以得到原始的報文[5]。
我國配電自動化正在逐步成長,由配電主站、子站和饋線終端構(gòu)成的三層結(jié)構(gòu)是最常見的并得到廣泛贊同,光纖通信作為主干網(wǎng)的通信方式也得到認可[6]。由于電力系統(tǒng)信息安全的特殊重要性,國內(nèi)外對電網(wǎng)通信保密性的高度重視,促進了加密機的發(fā)展,加密機在電網(wǎng)中的應(yīng)用有效提高了安全性。目前,電力通信中接入的終端越來越多,信息的吞吐量也越來越多,對加密機的性能要求也隨之增加。然而配電自動化通信加密機在國產(chǎn)化的兆芯平臺上吞吐性能是120 Mb/s,這不足以滿足性能需求,需要對加密機進行優(yōu)化。在目前的配電自動化中配電主站需要接入大量的配電終端,為了滿足配電自動化中的加/解密需求,要求加密機的吞吐性能要在250 Mb/s以上。
影響設(shè)備性能的因素有很多。首先,從軟件架構(gòu)來看,軟件架構(gòu)是一個系統(tǒng)草圖,它描述的是構(gòu)成系統(tǒng)的抽象組件,各組件之間的連接明確和較為仔細地描述組件之間的通訊[7]。從具體實物來看,這些抽象組件會被細化為具體的實物,比如具體某個類或?qū)ο?。從面向?qū)ο蠓矫鎭砜?各個組件的連接需要用接口來實現(xiàn)。構(gòu)架是一個應(yīng)用系統(tǒng)的基礎(chǔ),往往對性能有著決定性的影響,但是改動起來也是最困難的,不到萬不得已一般不能隨意變動架構(gòu)。其次,從組件的具體實現(xiàn)上,比如算法代碼的優(yōu)化,空間換時間的運用,調(diào)整線程或者連接池的大小同樣也可以提高性能指標(biāo)。
加密機的軟件架構(gòu)如圖1所示。
圖1 加密機軟件構(gòu)架
圖1中程序的執(zhí)行路徑是應(yīng)用進程通過加密線程接到API接口,從連接池中取出一個已建立的可以使用的連接socket對象,將通信數(shù)據(jù)寫入socket發(fā)送到服務(wù)端,服務(wù)端利用epoll偵聽到數(shù)據(jù),然后從加密線程池中取出一個可用的加密線程,將socket對象交給此線程,加密線程讀出數(shù)據(jù),使用加密卡同步接口進行加/解密,加密卡返回數(shù)據(jù)后,加密線程再將數(shù)據(jù)寫入socket對象發(fā)送給客戶端。
加密機為應(yīng)用進程提供用于二次開發(fā)的API軟件包,軟件包內(nèi)使用連接池技術(shù),提前與服務(wù)器建立多個連接,讓應(yīng)用進程的多個業(yè)務(wù)線程共享這些連接,客戶端和服務(wù)端使用TCP連接,加密服務(wù)使用epoll機制偵聽客戶端連接和數(shù)據(jù)收發(fā),加密服務(wù)同時使用線程池技術(shù)和加密卡交互,數(shù)據(jù)共享這些加密線程。
多線程技術(shù)是充分利用和發(fā)揮CPU性能的一種現(xiàn)代計算機技術(shù),采用并發(fā)執(zhí)行的方式來實現(xiàn)。通過把程序分段,看成是許多個子任務(wù),這些子任務(wù)并發(fā)執(zhí)行。在單核CPU時,并發(fā)執(zhí)行是把處理器分為多個時間片,每個時間片依次執(zhí)行各個任務(wù)。因為每一個時間片的時間很短,所以可以看成每個程序都有處理器單獨服務(wù),從而達到多個程序同時運行的效果。也就是單核模擬多核,能同時提供多個服務(wù),增強用戶體驗和程序的效率。在多核CPU時,能實現(xiàn)真正的多任務(wù)并發(fā)。連接池技術(shù)的使用可以減少時間從而提高性能,這些預(yù)先準(zhǔn)備好的連接被任何需要它們的線程使用,這樣可以實現(xiàn)連接的集中管理,不用每個業(yè)務(wù)線程都去創(chuàng)建一個連接,而只是在需要的時候利用其中一個連接,從而節(jié)省網(wǎng)絡(luò)資源。連接池可以為動態(tài)實現(xiàn)的,連接數(shù)在設(shè)定的區(qū)間內(nèi)根據(jù)實際業(yè)務(wù)需要動態(tài)增加或者減少。
對設(shè)備進行分析,可以將性能分解到多個部分,通過測定分析各部件的性能情況,找到優(yōu)化方法。
需要保證加密卡的性能滿足要求,如果瓶頸在加密卡,那么提高加密卡的運算速度或者更換性能更好,成本也就更高的加密卡,就可以顯著提升加密機的性能。
應(yīng)用程序的性能優(yōu)化,除了硬件升級,最主要的是代碼本身的優(yōu)化,一般來說滿足二八原則,20%的代碼消耗80%的性能,找到那20%的代碼,就可以優(yōu)化對應(yīng)的80%的性能。常用的方法包括:
1)調(diào)整配置參數(shù),比如線程池/連接池的大小,應(yīng)用數(shù)據(jù)緩存的大小,IO數(shù)據(jù)緩存的大小,系統(tǒng)資源的限制等。通過檢查分析這些參數(shù),往往能找到制約性能的點。
2)算法優(yōu)化,比如數(shù)據(jù)結(jié)構(gòu)的設(shè)計,能否利用cpu_cache,循環(huán)語句或者條件語句的效率,并發(fā)鎖的運用等等。通過一些性能分析工具,比如perf,能定量分析各個函數(shù)調(diào)用的時間占比,算法的cache利用率。
構(gòu)架調(diào)整影響比較大,但是效果經(jīng)常比較顯著,能突破既有架構(gòu)的限制。比如修改單線程執(zhí)行為多線程并發(fā)執(zhí)行,更換通訊方式從TCP改成UDP通訊,從采用內(nèi)核協(xié)議棧改為使用用戶態(tài)協(xié)議棧,更換使用的數(shù)據(jù)庫等。比如TCP使用了握手、確認、窗口、重傳、擁塞控制等機制,這些機制采用的算法很難提升,而UDP是一個無狀態(tài)的傳輸協(xié)議,不需要這些機制,所以它寬帶需求低,而實時性非常高。
我們從這三個方面入手,并且借助一些性能測試工具得到定量數(shù)據(jù),進行分析,找出瓶頸。
采用的性能測試方法和工具如下:
1)加密卡測試程序,檢測加密卡的運算速度。
2)模擬客戶端程序,調(diào)用加密機客戶端API,檢測加密機服務(wù)性能。
3)Perf工具,查看代碼中具體的耗時函數(shù),代碼優(yōu)化的基礎(chǔ)。
4)Netstat工具,可觀察TCP的連接情況,查看連接池的使用情況。
5)Sar工具,從多方面對系統(tǒng)的活動進行查看,包括:文件讀寫情況、系統(tǒng)調(diào)用使用情況、磁盤I/O、CPU的效率、內(nèi)存的使用狀況、進程活動及IPC有關(guān)活動等[8]。
加密卡是一種用于PCI-E接口的硬件加密設(shè)備,它作為加密設(shè)備或應(yīng)用服務(wù)器中加密算法加速和密鑰保護的組件,用于完成數(shù)據(jù)加密、身份驗證和數(shù)據(jù)防護。在加/解密算法的早期,大多數(shù)使用軟件實現(xiàn)設(shè)備的安全。主要原因是以往的信息量不大,基本上不會要求高性能的技術(shù)指標(biāo),能夠滿足當(dāng)時的需求。然而,伴隨著配電自動化技術(shù)的發(fā)展,需要連接的配電終端快速增加,對于加密卡也提出了更高的要求。加/解密速度已經(jīng)成為目前產(chǎn)品的一大指標(biāo),標(biāo)志著加解密設(shè)備產(chǎn)品安全性能的瓶頸。因此需要從新的方面考慮,通過加密硬件的使用從而實現(xiàn)其吞吐量的增加。加密卡是通過使用SM1、SM2、SM3、SM4等加密硬件來實現(xiàn)的,加密過程中大部分的實現(xiàn)都與加密卡有關(guān),即算法是硬件機制實現(xiàn)中最繁瑣的。還可以使用加密卡的壓縮功能,相應(yīng)的就可以使數(shù)據(jù)處理速度得到提升。
通過對現(xiàn)有加密卡進行性能測試,結(jié)果如圖2所示。
圖2 加密卡性能測試結(jié)果
一次加密需要調(diào)動兩次加密卡。觀察結(jié)果可以發(fā)現(xiàn),對256字節(jié)的小包加密性能可以達到677.79/2=338.89 Mb/s,足以滿足要求。目前通過升級加密卡來提升性能的可操作性不強,提升的效果也不明顯??紤]從其他方面進行提升。
使用perf工具測試程序運行,得到函數(shù)耗時情況如圖3所示。
圖3 perf查看耗時函數(shù)
可以發(fā)現(xiàn)malloc/free占用了比較大的時間,查看代碼,發(fā)現(xiàn)在數(shù)據(jù)接收、處理、發(fā)送過程中有大量的堆分配調(diào)用,結(jié)合實際情況考慮兩個方向:
1)使用線程局部變量替換堆分配,在收發(fā)過程中使用,減少堆分配的次數(shù),完全省去了調(diào)用時間。
2)使用第三方j(luò)emalloc庫malloc函數(shù)替換c運行時庫的標(biāo)準(zhǔn)堆分配函數(shù),獲得性能的提升。
jemalloc提供的堆分配器,其最大的優(yōu)勢是多線程分配能力。在多核環(huán)境下,進程效率的最大瓶頸已經(jīng)變成如何用好多線程和如何避免死鎖。jemalloc實現(xiàn)了盡可能地避免死鎖,從而加快多線程環(huán)境下的內(nèi)存申請和釋放。
對原有代碼進行改進,改進如下,在這里挑出了三個部分進行展示。
1)頭文件部分
#include "fm_def.h"
#include
#include
#include
……
2)使用線程本地存儲分配讀寫緩沖區(qū)
_ _thread unsigned char
TransferDataIn[MAXIUM_TRANSFERBUF_LEN];
__thread unsigned char TransferDataOut[MAXIUM_TRANSFERBUF_LEN];
3)緩沖區(qū)的實際使用
void* doData(void* ptr)
{
int sockfd;
int len=0;
int rv=0;
int sock;
unsigned char *receiveBuff=NULL;
unsigned char *sendBuf=NULL;
struct epoll_event ev,pev;
ARG_ST* psinfo=(ARG_ST *)ptr;
struct epollData *ep;
int ord=0;
int totallen=0,sendBufLen=0;
int errflag=0;
void *pdev=g_hdev;
DEVICE_STATUS *pdevStatus=NULL;
OrderFunc pFunc=NULL;
recvhead recvh;
int TransferBufLen=0;
int TransferOffset=0;
pev.events=psinfo->ev.events;
ep=(struct epollData *)psinfo->ev.data.ptr;
sock=psinfo->sock;
free(psinfo);
if ((sockfd=ep->fd) < 0)
{
LOG_WriteLog(LOG,__FILE__,__LINE__,"dodata====>",errflag,NULL,0);
return 0;
}
memset(&ev,0x00,sizeof(struct epoll_event));
if(pev.events&EPOLLIN)
{
len=recv(sockfd,TransferDataIn,MAXIUM_TRANSFERBUF_LEN,0);
do{
if (len <=0)
{
……
break;
}
memcpy(&recvh,TransferDataIn,sizeof(int)*2);
ord=recvh.ord;
totallen=recvh.totallen;
TransferBufLen=totallen-len;
TransferOffset+=len;
if(totallen > len)
{
while(TransferBufLen > 0)
{
LOG_WriteLog(LOG,__FILE__,__LINE__,"Large message Transfer",totallen,NULL,0);
len=recv(sockfd,&TransferDataIn[TransferOffset],MAXIUM_TRANSFERBUF_LEN,0);
……
這個socket收發(fā)數(shù)據(jù)緩存區(qū)原來每次都用malloc從堆中分配,現(xiàn)在使用線程本地存儲,不再需要分配,實際測試發(fā)現(xiàn),減少堆分配和使用第三方堆分配函數(shù)將應(yīng)用性能提升了30%。
從加密機的架構(gòu)可以看到使用了多線程技術(shù)和連接池技術(shù)。通過使用“netstat-apn | grep 6666” 觀察TCP連接情況,發(fā)現(xiàn)只有幾十個連接,查看代碼,這個連接池在配置代碼中是固定的,是有限制的,所以在代碼中加大連接池,將最大連接數(shù)從32調(diào)整為200,經(jīng)過測試發(fā)現(xiàn),性能提升了30%。
通過代碼方面的優(yōu)化,加密機的性能得到了提升,但是仍未到達設(shè)計要求。接下來考慮從架構(gòu)出發(fā),改變通信方式,從而達到目標(biāo)。
從客戶端發(fā)送信息到服務(wù)端,中間需要通過加密機的加密。首先,信息發(fā)送到加密機上,通過加密后,發(fā)送給服務(wù)端。其中涉及到TCP/IP傳輸,在是否基于連接方面,TCP是面向連接的協(xié)議,而UDP是無連接的協(xié)議??梢岳斫鉃槭褂肨CP是需要建立連接,而使用UDP時是可以不用建立連接就能夠進行數(shù)據(jù)的發(fā)送。并且使用UDP比使用TCP可以達到更好的實時性和更高的工作效率,主要應(yīng)用在高速傳輸和高實時性的通信模式中。但是UDP沒有滑動窗口實現(xiàn)擁塞機制,容易導(dǎo)致丟包。但在我們的應(yīng)用場景中,加密是同步方式,只有數(shù)據(jù)返回后才會送下一個報文。因此天然的控制,不容易堵塞,所以,在這里把服務(wù)端和客戶端的傳輸方式改為UDP傳輸。
通過使用UDP傳輸,更好的增加了加密機的性能。通過實際的測試可以發(fā)現(xiàn),達到了設(shè)計要求。
首先我們把主機、交換機、加密機用網(wǎng)線連接好。其次配置好主機與加密機的IP地址,然后開始進行加密機的性能測試,如圖4所示。具體的參數(shù)如表1所示。
圖4 連接示意圖
表1 設(shè)備參數(shù)
在基于現(xiàn)有加密機的基礎(chǔ)上進行升級,可以得到一個性能更加優(yōu)越的加密機。為了驗證本文所提出的設(shè)計要求,使用性能工具進行測試,實際性能到達了280 Mb/s。實現(xiàn)了更高的運行速度,已經(jīng)達到了設(shè)計要求。同時,我國信息加密仍具有許多問題,例如:核心技術(shù)設(shè)備受制于人,信息加密基礎(chǔ)設(shè)施的安防能力較差,網(wǎng)絡(luò)通訊體系不完善等[9]。
加密機的性能得以提升,主要是通過代碼優(yōu)化以及架構(gòu)調(diào)整兩方面實現(xiàn)的。運用基于數(shù)字證書的認證技術(shù)及加密技術(shù),實現(xiàn)配電主站和終端之間的雙向身份鑒別和業(yè)務(wù)數(shù)據(jù)的加密,保障數(shù)據(jù)的完整性和機密性[10]。經(jīng)過實際的測試,發(fā)現(xiàn)本文提出的方法可以達到目標(biāo),滿足要求,具有一定的可操作行。優(yōu)化后的加密機使電力系統(tǒng)通信有了更加及時、高效的通信能力,使加密機適應(yīng)在高性能要求的環(huán)境中,可多機并行工作在各種類型的密碼安全應(yīng)用系統(tǒng)。向信息安全傳輸系統(tǒng)給出高性能的數(shù)據(jù)加、解密服務(wù),確保配電自動化系統(tǒng)的通信安全。同時可以滿足我國電力行業(yè)高速發(fā)展,滿足電力系統(tǒng)通信的傳輸要求,保障電力通信的機密性,有效防止違法分子惡意破壞的攻擊,防止由此引發(fā)電力系統(tǒng)事故。