李春杰+張啟軍+譚嘉瑞+顏智潤(rùn)
摘 要:對(duì)文件內(nèi)容加密,可有效解決數(shù)據(jù)泄露問(wèn)題。目前傳統(tǒng)的第三方軟件多采用非透明式加密,對(duì)用戶(hù)而言,操作不便;新型的堆疊式文件加密方案可以有效解決透明性問(wèn)題,但此類(lèi)設(shè)計(jì)方案實(shí)施較為復(fù)雜,并存在內(nèi)核版本依賴(lài)性。文中采用Hook機(jī)制,通過(guò)監(jiān)控用戶(hù)對(duì)指定文件目錄進(jìn)行操作,捕獲用戶(hù)對(duì)該目錄具體文件的訪(fǎng)問(wèn);自動(dòng)調(diào)用應(yīng)用層的加解密模塊,完成對(duì)具體文件的加解密,解決透明性問(wèn)題。由于該系統(tǒng)的加解密功能在應(yīng)用層實(shí)現(xiàn),與具體文件系統(tǒng)無(wú)關(guān),因此又可以有效簡(jiǎn)化系統(tǒng)設(shè)計(jì),災(zāi)難恢復(fù)性強(qiáng),穩(wěn)定性高。
關(guān)鍵詞:數(shù)據(jù)加密;進(jìn)程間約束;消息Hook機(jī)制;鎖機(jī)制
中圖分類(lèi)號(hào):TP309.7;TP316.81 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):2095-1302(2018)02-00-03
0 引 言
最近幾年,基于Linux內(nèi)核開(kāi)發(fā)的操作系統(tǒng)逐漸從服務(wù)端走向用戶(hù)終端。尤其某些單位,從服務(wù)器到個(gè)人終端都以L(fǎng)inux作為系統(tǒng)支撐。因此,對(duì)于存放在Linux上的敏感數(shù)據(jù)進(jìn)行加密保護(hù),已成為一個(gè)急需解決的問(wèn)題。
多數(shù)第三方加密軟件均采用非透明式文件存儲(chǔ)方式,需要用戶(hù)在打開(kāi)指定文件時(shí)調(diào)用解密模塊;同樣,當(dāng)用戶(hù)關(guān)閉文件時(shí),需要調(diào)用加密模塊,導(dǎo)致體驗(yàn)效果不好。
新型堆疊式文件加密系統(tǒng)[1]雖然可以解決用戶(hù)透明性問(wèn)題,但需要重新設(shè)計(jì)一個(gè)新的文件管理層,用以對(duì)文件加密,因此需要對(duì)加密文件系統(tǒng)進(jìn)行重新設(shè)計(jì)。此類(lèi)方案對(duì)于設(shè)計(jì)者而言,需要深入掌握Linux各方面的知識(shí),如文件系統(tǒng)管理、內(nèi)存管理、驅(qū)動(dòng)設(shè)計(jì)等。雖然設(shè)計(jì)方案在理論上可行,但在系統(tǒng)的具體實(shí)現(xiàn)過(guò)程中卻十分復(fù)雜,而且開(kāi)發(fā)周期長(zhǎng),成本昂貴,短期內(nèi)看不出測(cè)試結(jié)果。
1 整體方案設(shè)計(jì)
該系統(tǒng)使用文件鎖[2]和消息Hook機(jī)制[3]進(jìn)行設(shè)計(jì),既可以有效解決用戶(hù)透明性問(wèn)題,又可以降低整體設(shè)計(jì)難度。如圖1所示,系統(tǒng)中目錄A作為被監(jiān)控目錄,用于存放需要加密的文件,目錄B可以視為緩存目錄或者備份目錄。當(dāng)明文文件被存放到目錄A中時(shí),加密子進(jìn)程在目錄B中創(chuàng)建一個(gè)新的臨時(shí)文件,用以保存加密之后的密文。當(dāng)明文文件加密完成后,再利用目錄B中的臨時(shí)密文文件替換目錄A中的文件。同樣,當(dāng)需要對(duì)目錄A中的密文文件解密時(shí),讀取目錄B中的臨時(shí)密文文件,然后調(diào)用解密子進(jìn)程對(duì)其解密,最后將解密之后的數(shù)據(jù)覆蓋目錄A的密文文件。
整體方案只需調(diào)用Linux提供的接口就可以完成設(shè)計(jì),且絕大部分?jǐn)?shù)據(jù)處理過(guò)程都位于應(yīng)用層。即便系統(tǒng)遇到不可控因素而產(chǎn)生災(zāi)難性后果,也可以在現(xiàn)有文件系統(tǒng)中找到保存完整的加密數(shù)據(jù),對(duì)其進(jìn)行解密操作,有效解決文件恢復(fù)問(wèn)題??梢钥闯?,基于應(yīng)用層的方案設(shè)計(jì)無(wú)須對(duì)Linux內(nèi)核進(jìn)行深層次的修改,降低了開(kāi)發(fā)難度。
2 關(guān)鍵技術(shù)點(diǎn)
目錄A和目錄B間的數(shù)據(jù)交換需要多個(gè)子進(jìn)程先后進(jìn)行協(xié)調(diào)工作,包括維護(hù)子進(jìn)程、加密子進(jìn)程、解密子進(jìn)程。如果用戶(hù)操作目錄A以及目錄A中的文件,那么維護(hù)子進(jìn)程就能夠捕捉到用戶(hù)的操作,并且通知其他子進(jìn)程進(jìn)行后續(xù)操作。
系統(tǒng)方案的設(shè)計(jì)需要解決兩個(gè)技術(shù)點(diǎn),即監(jiān)控目錄和進(jìn)程間控制。
2.1 監(jiān)控目錄
在Linux內(nèi)核最新版本中添加了監(jiān)控操作文件的消息Hook模塊,即inotify,利用inotify作為實(shí)現(xiàn)監(jiān)控目錄的核心。
監(jiān)控模塊經(jīng)過(guò)初始化后,返回相應(yīng)的監(jiān)控實(shí)例id,然后將需要監(jiān)控的對(duì)象路徑添加到監(jiān)控實(shí)例中,這些對(duì)象可以是文件,也可以是文件目錄。若不監(jiān)控該對(duì)象,則可以從監(jiān)控實(shí)例中移除。
監(jiān)控用戶(hù)操作文件并產(chǎn)生消息隊(duì)列的過(guò)程如圖2所示。當(dāng)用戶(hù)對(duì)監(jiān)控目錄A中的文件進(jìn)行操作時(shí),消息Hook模塊便對(duì)虛擬文件系統(tǒng)(VFS)進(jìn)行監(jiān)控,將用戶(hù)的操作類(lèi)型通過(guò)消息方式發(fā)送到應(yīng)用層的消息隊(duì)列中,使得后臺(tái)維護(hù)子進(jìn)程(通過(guò)輪詢(xún)方式)能夠?qū)崟r(shí)捕捉。
維護(hù)子進(jìn)程通過(guò)讀取消息隊(duì)列[4]判斷產(chǎn)生的事件并調(diào)用對(duì)應(yīng)的加密或解密子進(jìn)程。通常用戶(hù)在訪(fǎng)問(wèn)一個(gè)文件時(shí),可能會(huì)產(chǎn)生連續(xù)多個(gè)消息事件。例如,用戶(hù)打開(kāi)一個(gè)加密文件,監(jiān)控模塊首先產(chǎn)生IN_OPEN消息事件,然后產(chǎn)生IN_WRITE消息事件,最后產(chǎn)生IN_CLOSE消息事件。因此,在監(jiān)控一個(gè)對(duì)象時(shí),需要維護(hù)子進(jìn)程依次捕獲該對(duì)象所產(chǎn)生的一系列消息事件,判斷當(dāng)前監(jiān)控對(duì)象需要進(jìn)行的操作。
2.2 進(jìn)程間控制
用戶(hù)使用編輯器等軟件打開(kāi)目錄A中的密文文件,維護(hù)子進(jìn)程自動(dòng)調(diào)用加解密模塊完成文件解密過(guò)程,將解密之后的明文數(shù)據(jù)呈現(xiàn)給用戶(hù)。在解密過(guò)程中,采用文件鎖方式使用戶(hù)進(jìn)程產(chǎn)生等待,便于解密模塊解密。
但多數(shù)編輯軟件在打開(kāi)文件時(shí)不檢查文件鎖,而是直接讀取文件內(nèi)容,因此用戶(hù)讀取的是密文數(shù)據(jù)。為了使這些軟件產(chǎn)生等待,在文件打開(kāi)時(shí),需要將這些軟件產(chǎn)生的進(jìn)程強(qiáng)制性地檢查文件是否被鎖定。由于這些進(jìn)程打開(kāi)的文件最終都需要調(diào)用內(nèi)核層中的open函數(shù),所以需要修改Linux內(nèi)核中系統(tǒng)定義的open部分[5]。
在Linux內(nèi)核中需要添加文件鎖檢測(cè)函數(shù),命名為myFlock。由于內(nèi)核中Flock的系統(tǒng)定義只能提供給上層進(jìn)行系統(tǒng)調(diào)用而不能直接被內(nèi)核層的其他函數(shù)調(diào)用,所以需要在do_sys_open中調(diào)用自定義的鎖。由于內(nèi)核中的函數(shù)都通過(guò)EXPORT_SYMBOL等方式輸出全局信號(hào)量[6],因此,F(xiàn)lock和myFlock可以通過(guò)調(diào)用全局輸出的信號(hào)量來(lái)共享緩存隊(duì)列,從而使得其他進(jìn)程在打開(kāi)文件時(shí)強(qiáng)制檢查鎖。此外,內(nèi)核層中進(jìn)程之間的約束過(guò)程如下:
(1)在控制進(jìn)程中,密文文件被維護(hù)子進(jìn)程調(diào)用flock(),維護(hù)子進(jìn)程持有加密文件鎖;
(2)將與密文文件相關(guān)的信息加入緩存隊(duì)列中;
(3)其他進(jìn)程打開(kāi)文件需要調(diào)用open()函數(shù),在do_sys_open()返回文件描述符之前[7],需要先調(diào)用myFlock()自定義鎖;endprint
(4)若該文件是被監(jiān)控文件,則其他進(jìn)程的訪(fǎng)問(wèn)需要等待文件鎖釋放;
(5)do_sys_open()將通過(guò)系統(tǒng)調(diào)用open()返回文件描述符給其他進(jìn)程;
(6)其他進(jìn)程讀取文件。
文中詳述了利用文件鎖方式進(jìn)行進(jìn)程間控制的過(guò)程,使得多個(gè)并發(fā)進(jìn)程能夠有序調(diào)度。如果打開(kāi)的對(duì)象不是被監(jiān)控文件,那么其他進(jìn)程在內(nèi)核層中獲取鎖之后應(yīng)該立即釋放文件鎖,避免整個(gè)系統(tǒng)被鎖死。
3 模塊方案設(shè)計(jì)
雖然系統(tǒng)中有多個(gè)子進(jìn)程先后協(xié)調(diào)工作,但為了降低方案設(shè)計(jì)的復(fù)雜度,可以將系統(tǒng)分為加密過(guò)程和解密過(guò)程[8]兩部分。
3.1 讀解密操作
對(duì)于用戶(hù)而言,監(jiān)控目錄下存放的文件雖然以密文數(shù)據(jù)的形式存放在磁盤(pán)中,但當(dāng)用戶(hù)訪(fǎng)問(wèn)文件時(shí),文件應(yīng)當(dāng)以明文形式呈現(xiàn)給用戶(hù)。
如圖3所示,當(dāng)用戶(hù)打開(kāi)一份密文文件時(shí),需要先讓用戶(hù)等待。此時(shí)的監(jiān)控模塊產(chǎn)生IN_OPEN消息并插入到消息隊(duì)列中,然后維護(hù)子進(jìn)程捕獲該消息,調(diào)用解密子過(guò)程直到解密完成后,返回維護(hù)子進(jìn)程使得維護(hù)子進(jìn)程釋放目錄A下的文件鎖,用戶(hù)再讀取解密文件時(shí)便可以獲得明文。系統(tǒng)的解密過(guò)程如下:
(1)維護(hù)進(jìn)程初始化時(shí)會(huì)掃描目錄A下的文件及目錄,并把這些目錄和文件的絕對(duì)路徑放入到已加密文件的監(jiān)控鏈表中,同時(shí)給文件添加文件鎖(系統(tǒng)默認(rèn)目錄A中已存在的文件為密文或目錄為空);
(2)用戶(hù)打開(kāi)目錄A中的加密文件2,監(jiān)控模塊產(chǎn)生IN_OPEN消息事件,由于文件鎖的存在,使得用戶(hù)進(jìn)程產(chǎn)生等待;
(3)維護(hù)子進(jìn)程通過(guò)不斷輪詢(xún)捕獲到該消息并查找已加密文件監(jiān)控鏈表,判斷該消息所代表的文件是否為密文;
(4)復(fù)制目錄A中的加密文件2到目錄B中;
(5)維護(hù)子進(jìn)程調(diào)用解密程序,解密程序讀取目錄B中的加密文件2并解密,將解密之后的數(shù)據(jù)寫(xiě)入目錄A中的解密文件2中;
(6)解密完成,解密程序?qū)⒓用芪募?從已加密文件監(jiān)控鏈表中移除,并將其添加到待加密的文件鏈表(在監(jiān)控目錄A中以明文形式存在的文件)中;
(7)維護(hù)子進(jìn)程刪除目錄B中的加密文件2并釋放目錄A中解密文件2的文件鎖;
(8)用戶(hù)讀取解密文件2。
需要注意的是待加密的文件鏈表中存放的是目錄A中未加密的明文文件節(jié)點(diǎn),當(dāng)用戶(hù)讀取文件數(shù)據(jù)或者其他操作結(jié)束之后便關(guān)閉該文件并產(chǎn)生IN_CLOSE消息事件,此時(shí)就需要維護(hù)線(xiàn)程通過(guò)讀取待加密的文件鏈表,重新對(duì)該目錄A中的明文文件進(jìn)行加密處理。解密過(guò)程如圖4所示。
3.2 寫(xiě)加密操作
存在于目錄A下的明文文件可以來(lái)源于從其他目錄轉(zhuǎn)移到目錄A中的新明文文件,或者用戶(hù)讀取目錄A中的密文文件時(shí)通過(guò)讀解密操作之后留下的明文文件。針對(duì)第二種情況,在上述解密操作過(guò)程中,后臺(tái)子進(jìn)程已自動(dòng)將解密文件相關(guān)信息添加到了待加密文件鏈表中,當(dāng)IN_CLOSE消息到來(lái)時(shí)就可以通過(guò)加密程序?qū)γ魑奈募M(jìn)行加密操作。然而,對(duì)于第一種情況,監(jiān)控模塊也會(huì)產(chǎn)生對(duì)應(yīng)的IN_OPEN以及IN_CLOSE消息。因此,只要將監(jiān)控目錄中的新文件相關(guān)信息加入到待加密文件鏈表中,IN_CLOSE消息到來(lái)時(shí)就可通過(guò)加密程序?qū)π旅魑奈募M(jìn)行加密操作。如圖5所示,系統(tǒng)的加密過(guò)程如下:
(1)訪(fǎng)問(wèn)監(jiān)控目錄A并產(chǎn)生相應(yīng)消息事件;
(2)如果是一份新明文文件N,那么監(jiān)控模塊將依次產(chǎn)生IN_OPEN和IN_CLOSE等多個(gè)重要的消息;
(3)維護(hù)進(jìn)程首先掃描消息鏈表,得到IN_OPEN消息;
(4)將明文文件N的節(jié)點(diǎn)添加到待加密的文件鏈表中;
(5)維護(hù)子進(jìn)程繼續(xù)掃描消息隊(duì)列;
(6)維護(hù)子進(jìn)程掃描IN_CLOSE消息,在待加密文件鏈表里找到該消息代表的文件;
(7)調(diào)用加密程序?qū)ξ募M(jìn)行加密;
(8)加密程序完成后,將該文件節(jié)點(diǎn)從待加密文件鏈表中移除,并給該文件上鎖。
目錄A中的文件既存有明文文件,又存有密文文件。在寫(xiě)加密操作中,一些待加密的文件都通過(guò)待加密文件鏈表維護(hù)。
4 測(cè)試結(jié)果
文件加密系統(tǒng)初始化運(yùn)行,指定目錄A的絕對(duì)路徑。首先讀取路徑下的所有文件及子目錄。然后對(duì)整個(gè)目錄A的文件加密。最后,強(qiáng)行中止文件加密系統(tǒng)運(yùn)行。如圖6所示,打開(kāi)該目錄下的文件,顯示的是用戶(hù)無(wú)法閱讀的亂碼,如文本(txt),圖片(jpg)。
關(guān)閉上述所打開(kāi)的文件,再重新啟動(dòng)文件加密系統(tǒng)。因?yàn)橐呀?jīng)運(yùn)行過(guò)一次,所以需要讀取日志文件[9],但發(fā)現(xiàn)所有文件都已被加密。
再打開(kāi)上述文件,此時(shí)后臺(tái)維護(hù)子進(jìn)程啟動(dòng),調(diào)用解密子進(jìn)程完成文件解密過(guò)程,釋放文件鎖。如圖7所示,用戶(hù)讀取的文本(txt)為明文,圖片(jpg)無(wú)格式錯(cuò)誤,能夠進(jìn)行正常預(yù)覽。
5 結(jié) 語(yǔ)
本文主要采用文件鎖和消息Hook機(jī)制進(jìn)行系統(tǒng)設(shè)計(jì),因此需要多個(gè)子進(jìn)程之間的協(xié)調(diào)工作?;趹?yīng)用層的設(shè)計(jì),降低了整個(gè)系統(tǒng)的實(shí)現(xiàn)復(fù)雜度。同時(shí),兼容了各種文件系統(tǒng)格式,通過(guò)對(duì)監(jiān)控目錄的備份保證了數(shù)據(jù)的可恢復(fù)性。解密之后的文件可以對(duì)文件內(nèi)容進(jìn)行Hash校驗(yàn)[10],從而確定解密之后的文件是否與原始文件的內(nèi)容相同。
參考文獻(xiàn)
[1]刑常亮,卿斯?jié)h,李麗萍.一個(gè)基于Linux的加密文件系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與應(yīng)用,2005,41(17):101-104.
[2] Randal E Bryant , David OHallaron.Computer Systems: A Programmers Perspective[M].北京:機(jī)械工業(yè)出版社,2011.
[3]劉剛,趙劍川. Linux系統(tǒng)移植[M].北京:清華大學(xué)出版社,2011.
[4]邱鐵,周玉,鄧瑩瑩.Linux內(nèi)核API完全參考手冊(cè)[M].北京:機(jī)械工業(yè)出版社,2011.
[5] Wolfgang Mauerer. Professional Linux Kernel Architecture[M]. 北京:人民郵電出版社,2008.
[6] Neil Matthew,Richard Stones. Beginning Linux Programming [M].北京:人民郵電出版社,2000.
[7]龐麗萍,鄭然.操作系統(tǒng)原理與Linux系統(tǒng)實(shí)驗(yàn)[M].北京:機(jī)械工業(yè)出版社,2011.
[8]解雙建,原亮,郝琳,等.一種有效的RSA算法改進(jìn)方案[J].計(jì)算機(jī)應(yīng)用,2010,30(9):2293-2397.
[9]劉斌.基于Linux的文件實(shí)時(shí)備份系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D].保定:華北電力大學(xué),2014.
[10]徐術(shù)坤.Hash算法的研究及應(yīng)用[D].武漢:湖北工業(yè)大學(xué),2006.endprint