李春杰 孫玉強(qiáng) 徐 楷 顏智潤
(中國科學(xué)技術(shù)大學(xué)蘇州研究院 江蘇 蘇州 215000)
近年來,移動終端設(shè)備領(lǐng)域的發(fā)展十分迅猛,智能手機(jī)成了新時代生活的必需品,短短幾年間,Android已經(jīng)成為了最熱門的智能終端開發(fā)平臺之一[1]。如今普通用戶習(xí)慣使用智能移動設(shè)備拍攝照片,對照片進(jìn)行傳播和分享。但智能移動設(shè)備上保存的大量照片卻產(chǎn)生了隱私泄露的隱患[2]。在Android移動手機(jī)平臺上,安全防護(hù)是一個重要的研究方向,以圖片加密為主要功能的隱私保護(hù)是其中很重要的一個功能需求[3]。
以往在Android移動手機(jī)上實(shí)現(xiàn)圖片加密,用戶通常會通過安裝加密軟件來解決這個問題。不過現(xiàn)有多數(shù)Android圖片加密軟件的加密過程十分繁瑣,每拍攝一張新的照片都需要用戶手動進(jìn)行加密,使得加密的實(shí)時性很差,用戶體驗(yàn)非常糟糕。于是我們設(shè)計(jì)了一款名為“透明加密助手”的軟件,能夠以對用戶完全透明的方式將拍攝的照片進(jìn)行自動加密,在提升用戶體驗(yàn)的同時還能保障安全性能。
當(dāng)用戶需要對拍攝的照片進(jìn)行自動加密時,首先打開本軟件并保持其在后臺運(yùn)行,之后用戶在Android手機(jī)自帶的相機(jī)軟件上進(jìn)行拍照操作,生成的照片都會自動被本軟件捕獲到并進(jìn)行加密存儲。從捕獲照片到加密存儲,這一過程完全不需要用戶參與,其實(shí)現(xiàn)過程是不可見的,因此用戶在每次拍照后無需對生成的照片進(jìn)行單獨(dú)的加密操作,只需保證本軟件在后臺運(yùn)行即可。此外本軟件還集成了解密功能,當(dāng)用戶需要還原被加密的照片時,進(jìn)入本軟件,可以瀏覽到所有被加密的照片,點(diǎn)擊照片對應(yīng)的“解密”按鈕,就可以將照片還原。解密過程由用戶參與,用戶可以自由選擇需要解密的照片。透明加密助手軟件的功能示意圖如圖1所示。

圖1 透明加密助手功能示意圖
根據(jù)軟件的功能實(shí)現(xiàn),本軟件的結(jié)構(gòu)應(yīng)分為三個層次。第一層為視圖層,本軟件的加密過程對用戶完全透明,解密過程則需要用戶的參與,因此圖形用戶界面是必不可少的。第二層為業(yè)務(wù)層,這是結(jié)構(gòu)中最重要的一層,軟件主要的功能實(shí)現(xiàn)都由業(yè)務(wù)層來承擔(dān),其核心的部分為監(jiān)聽模塊[4]、加密模塊、存儲模塊,以及解密模塊。第三層為數(shù)據(jù)庫層,本軟件的操作對象是圖片文件,對文件的操作必然要涉及文件的路徑,而加密與解密的過程則離不開密鑰,因此這些重要數(shù)據(jù)都需要存儲于數(shù)據(jù)庫中。軟件的架構(gòu)圖如圖2所示。

圖2 透明加密助手軟件架構(gòu)圖
透明加密助手的工作原理為:在軟件登錄成功且處于運(yùn)行期間,當(dāng)用戶進(jìn)行拍照操作時,監(jiān)聽模塊會捕獲到拍照動作并啟動加密模塊對剛生成的照片進(jìn)行加密處理,加密成功后存儲模塊會對密文進(jìn)行存儲;當(dāng)用戶需要解密照片時,點(diǎn)擊照片對應(yīng)的“解密”按鈕會啟動解密模塊完成解密操作,之后密文會被刪除,原始照片將被還原至系統(tǒng)圖庫中。透明加密助手的工作流程如圖3所示,從圖中可以看出,除了基本的加密與解密功能外,本軟件的功能實(shí)現(xiàn)還必須解決如下四個方面的技術(shù)重點(diǎn):

圖3 透明加密助手工作流程圖
我們不希望在本軟件中集成拍照功能,這樣做一是浪費(fèi)資源,二是會強(qiáng)行改變用戶的使用習(xí)慣,因?yàn)橛脩艨赡芨?xí)慣使用系統(tǒng)自帶的相機(jī)軟件。而這便會帶來一個問題,就是我們不知道拍照軟件的底層代碼,因此如何捕獲其拍照動作便是一個重點(diǎn)。
本軟件的加密對象是照片,而要對照片文件進(jìn)行加密操作,必須獲得其絕對路徑,即存儲路徑加文件名。由于本軟件不集成拍照功能,因此照片的存儲路徑及照片的命名規(guī)則均是由系統(tǒng)相機(jī)的代碼實(shí)現(xiàn)的,這樣一來我們便不能通過文件名獲取到剛拍攝的照片了。
在對目標(biāo)照片進(jìn)行加密后,雖然無法查看照片內(nèi)容了,但是仍然存在加密后的文件被惡意刪除或誤刪除的可能,因此加密后的文件仍然要對用戶保持不可見狀態(tài)。這一功能的實(shí)現(xiàn)有兩種解決思路:一是加密后的文件仍存儲在相機(jī)軟件的默認(rèn)路徑下,然后將其設(shè)為不可見;二是將加密后的文件移至本軟件創(chuàng)建的文件夾下,并設(shè)該文件夾為不可見。我們需從這兩個方法中選出最優(yōu)的一個。
在解密的過程中,由于加密后的文件路徑以及加密算法對應(yīng)的密鑰都是已知的,因此將密文還原為照片并不困難。但是當(dāng)軟件加密了多張照片后,用戶需要解密哪一張照片是不確定的,即用戶在進(jìn)入本軟件后,需要看到已被加密的照片才能決定解密哪一張。因此如何在照片已被加密的情況下查看原始照片便是解密功能實(shí)現(xiàn)的重點(diǎn)。
針對軟件功能實(shí)現(xiàn)的四項(xiàng)技術(shù)難點(diǎn),我們在調(diào)研相關(guān)資料之后,給出如下解決方案。
在查閱Android Developer(安卓開發(fā)者)文獻(xiàn)后,我們發(fā)現(xiàn)在Android API14即Android 4.0之后,Google在Camera中添加了一個action,在拍攝照片后系統(tǒng)會發(fā)出一條值為:“android.hardware.action.NEW_PICTURE”的無序廣播[5],并且這條廣播是在照片文件生成后發(fā)出的,即在照片存儲到默認(rèn)路徑下后可以監(jiān)聽到這條廣播。進(jìn)一步調(diào)研相關(guān)內(nèi)容后,我們發(fā)現(xiàn)除了官方給出的這個action之外,其實(shí)在照片拍攝完成后,系統(tǒng)相機(jī)軟件會自動發(fā)出另一條值為:“com.android.camera.NEW_PICTURE”的無序廣播,這條廣播并未寫進(jìn)官方的文檔,但是在實(shí)際的商業(yè)應(yīng)用中,這條廣播也經(jīng)常會用到。
于是我們可以創(chuàng)建一個名為“CameraAction_Rece-iver”的類,讓它繼承BroadcastReceiver作為廣播接收器,并重寫其onReceive()方法,創(chuàng)建Intent的實(shí)例,在接收到系統(tǒng)相機(jī)軟件發(fā)出的廣播后用Intent啟動一個Service,由這個Service完成后續(xù)操作。我們使用靜態(tài)注冊的方式在AndroidManifest.xml文件中對該廣播接收器進(jìn)行注冊,在
在CameraAction_Receiver接收到廣播后,通過Intent啟動一個Service,在該Service中可以進(jìn)行查找照片、移動照片及加密照片等操作。我們創(chuàng)建一個名為“Bitmap_Service”的類,讓它繼承IntentService,繼承IntentService的好處是在代碼執(zhí)行完畢后服務(wù)會自動關(guān)閉,且只需重寫一個onHandleIntent()方法。由于我們不知道相機(jī)軟件的底層代碼,所以無法通過文件名來查找目標(biāo)照片。但是Android本身提供了一個多媒體數(shù)據(jù)庫MediaStore,它包含了Android手機(jī)上的所有多媒體信息可供外界查看調(diào)用。查找數(shù)據(jù)庫中的內(nèi)容需要使用接口ContentResolver[6],而ContentResolver對數(shù)據(jù)的訪問則是通過URI,每一個URI地址值都唯一對應(yīng)一個資源文件。因?yàn)槲覀儾檎业哪繕?biāo)只是圖片文件,且文件是處于外部存儲空間中的,所以查找的范圍應(yīng)為“MediaStore.Images.Media.EXTERNAL_CONTENT_U-RI”,它是ContentProvider的URI地址值,指向所有圖片文件。在確定了查找的范圍后,調(diào)用ContentResolver的query()方法在MediaStore.Images.Media.EXTERNA-L_CONTENT_URI中進(jìn)行查找。query()方法有5個入口參數(shù),第一個參數(shù)為指定的內(nèi)容提供者的URI地址值,即查找范圍;第二個參數(shù)為查找返回的結(jié)果,這里我們需要獲取到MediaStore中所有圖片的絕對路徑,即new String[]{MediaStore.Images.Media.DATA},結(jié)果會以數(shù)組的形式返回;第三個參數(shù)為查詢條件,即對返回的結(jié)果進(jìn)行篩選,這里我們沒有特殊的需求,所以可設(shè)為null;第四個參數(shù)需配合第三個參數(shù)使用,可對篩選后的數(shù)據(jù)進(jìn)行修改,當(dāng)然在這里也設(shè)為null;第五個參數(shù)為排序條件,即對返回結(jié)果按條件進(jìn)行排序,我們需要對MediaStore中的所有圖片按ID進(jìn)行排列,所以參數(shù)可設(shè)為MediaStore.Images.Media._ID +“DESC”,其中“DESC”表示降序排列。通過query()方法進(jìn)行查找,我們便能夠得到一個按ID降序排列的所有圖片的絕對路徑集合,顯然,剛拍攝生成的照片的絕對路徑一定處于這個集合的頂部。使用Cursor類對該集合進(jìn)行逐條遍歷,當(dāng)Cursor指向第一個數(shù)據(jù)時我們便得到目標(biāo)照片的絕對路徑了。
通過對市面上多數(shù)主流隱私保護(hù)軟件的調(diào)研,我們發(fā)現(xiàn)這些軟件都是采用將加密后的文件保存在自己生成的不可見目錄中的方法,以達(dá)到隔離加密文件的效果。這樣做符合隱私保護(hù)的邏輯:
(1) 加密后的文件不再屬于公共類文件,不應(yīng)該與無訪問權(quán)限的普通文件存儲在一個目錄中。
(2) 將本軟件加密生成的文件保存在軟件自身生成的目錄下便于管理。
(3) 將存儲加密文件的目錄設(shè)為不可見可以防止用戶將目錄誤刪除而造成文件丟失。
有了這個思路之后,我們可以采用將目標(biāo)照片文件從源存儲路徑移動到目的路徑同時進(jìn)行加密的方法使照片與用戶隔離起來,代碼仍在Bitmap_Service類中實(shí)現(xiàn)。上述獲取到的目標(biāo)照片的源存儲路徑可以通過cursor.getColumnIndex()獲得;目的路徑由三部分組成:手機(jī)外部存儲空間的根目錄,不可見文件夾名,加密文件的文件名。外部存儲空間的根目錄可由Environment.getExternalStorageDirectory()獲得,不可見文件夾名以“.”開頭,命名為“.TransEncryptHelper”,加密文件的文件名由UUID生成的32位唯一識別碼命名。得到了原路徑和目的路徑后,使用Java的I/O流來轉(zhuǎn)移照片。首先創(chuàng)建FileInputStream的實(shí)例從源路徑讀取字節(jié)數(shù)據(jù),然后創(chuàng)建OutputStream的實(shí)例將字節(jié)數(shù)據(jù)寫入目的路徑,寫入的同時對數(shù)據(jù)進(jìn)行加密。
加密的方法是創(chuàng)建加密算法的Util類,并生成算法的密鑰,之后調(diào)用Util類的encrypt()方法將數(shù)據(jù)流與密鑰一同加密,當(dāng)數(shù)據(jù)流全部寫入目的路徑后,得到的就是加密后的文件了。
與加密過程相比,本軟件解密功能的實(shí)現(xiàn)較為簡單,解密的過程需要用戶的參與,即由用戶來選擇需要解密的照片,點(diǎn)擊對應(yīng)的“解密”按鈕,通過加密算法的逆算法對加密文件進(jìn)行解密。解密功能實(shí)現(xiàn)的難點(diǎn)是在照片被加密的情況下,在軟件內(nèi)部看到原始圖片。為了解決這個問題,我們需要在捕獲到目標(biāo)照片后先生成其縮略圖,再對目標(biāo)照片進(jìn)行加密操作。
縮略圖由Bitmap類生成,但Bitmap類的構(gòu)造函數(shù)是私有的,需使用接口BitmapFactory對Bitmap進(jìn)行實(shí)例化,再調(diào)用其decodeFile()方法將Bitmap解析出來。在解析之前,先使用BitmapFacotry.Options實(shí)例化一個options對象,options的多個屬性可以指定decodeFile()方法的選項(xiàng),其中inSampleSize屬性可以設(shè)置解析出來后Bitmap的尺寸。解析出Bitmap后,便可以得到照片的縮略圖,調(diào)用Bitmap的compress()方法可以設(shè)置生成的縮略圖的格式,有JPG與PNG兩種格式可供選擇。最后,將生成的縮略圖保存在本軟件的私有目錄下,其他應(yīng)用便沒有權(quán)限訪問到該縮略圖,當(dāng)打開本軟件后,將縮略圖加載到ImageView控件上,用戶就可以看到被加密的照片了。
通過上述四個解決方案,我們基本可以實(shí)現(xiàn)透明加密助手的功能需求。但是在實(shí)際應(yīng)用中,我們還希望本軟件能在加密的安全性與時效性上都有較好的表現(xiàn),因此,針對目前常用的幾種加密算法,我們還需分別進(jìn)行測試,以選出最優(yōu)算法。
Android本身帶有Java提供的一些軟件包,如java.security和javax.crypto,為我們提供了多種加密算法的接口。在選擇加密算法之前,我們首先應(yīng)當(dāng)排除MD5算法[7],因?yàn)镸D5算法的加密過程是不可逆的,照片被加密后將無法還原。考慮到本軟件對安全性能的要求并不高,常用的加密算法如RSA-1024[8],DES[9]以及AES-128[10]的安全性都是可以滿足的,因此我們將針對這三種算法的加、解密效率分別進(jìn)行測試。測試環(huán)境如表1所示。

表1 軟件測試環(huán)境
我們首先對128位密鑰的AES加密算法進(jìn)行測試。為了使測試結(jié)果更加清晰準(zhǔn)確,我們將加密部分的代碼與解密部分的代碼寫在同一個Service下,在程序執(zhí)行完加密操作后立刻執(zhí)行解密操作。同時我們在程序中用Log.d()語句在logcat內(nèi)打印三條調(diào)試信息,這三條調(diào)試信息分別插入在捕獲到目標(biāo)照片的路徑、加密完成以及解密完成的代碼之后,打印調(diào)試信息的同時logcat會自動打印出當(dāng)前的時間信息,通過比較三條時間信息間的時間差就可以判斷算法的加、解密效率如何。
從圖4可以看出,AES-128算法對五張照片的加密耗時均不足1秒;對密文的解密耗時較加密耗時長,其中對白色墻壁照片的解密耗時最短,約為2.7秒,對電腦屏幕照片的解密耗時最長,約為24秒。
我們以同樣的方法對DES算法和RSA-1024算法分別進(jìn)行測試。結(jié)果顯示,DES算法較AES-128算法的性能略有下降,隨著照片文件大小的增加,其解密耗時增長較快;RSA-1024算法的性能較差,其對白色墻壁照片的加密耗時達(dá)到3分31秒,解密耗時則難以統(tǒng)計(jì)。最后我們從三種算法加密的五張照片中各選取三個典型的照片大小,將它們與加密后的密文大小進(jìn)行比較,如表2所示。可以看出RSA-1024算法對照片加密后,生成的加密文件大小有所增加,而DES算法和AES-128算法加密前后文件大小不變。
通過對安全性能、加密與解密效率以及加密前后文件大小三個方面進(jìn)行對比后,128位密鑰的AES算法無疑是最滿足需求的。
最后,我們在華為榮耀7上安裝“透明加密助手”軟件測試實(shí)現(xiàn)效果。首先在未打開本軟件的情況下用系統(tǒng)相機(jī)拍攝一張水杯的照片,這張照片會保存在“Camera”文件夾內(nèi)。接下來我們打開“透明加密助手”軟件,保持其在后臺運(yùn)行,并再次打開系統(tǒng)相機(jī)軟件拍攝一張簽字筆的照片,這時我們會發(fā)現(xiàn)在“Camera”文件夾下并沒有出現(xiàn)剛才拍攝的簽字筆照片。在Android手機(jī)已獲取root權(quán)限的情況下,打開Root Explorer文件管理器,找到“.TransEncryptHelper”文件夾,可以看到一個加密文件,文件名為UUID生成的32位唯一識別碼,這就是簽字筆照片被加密后的文件,如圖5所示。最后將加密文件還原,進(jìn)入本軟件,在“已加密圖片”界面可以看到被加密圖片的縮略圖,點(diǎn)擊解密按鈕進(jìn)解密,如圖6所示,解密后的簽字筆照片會還原到“Camera”文件夾下,如圖7所示。

圖5 加密文件

圖6 解密界面

圖7 簽字筆照片
Android操作系統(tǒng)是目前用戶數(shù)量最多的手機(jī)操作系統(tǒng)之一,本文針對Android用戶在日常使用中的痛點(diǎn),改進(jìn)了對用戶所拍攝照片的加密方法,在保證安全性的同時提升了用戶體驗(yàn)。經(jīng)過在華為榮耀7、紅米4A等多種型號手機(jī)上的測試,本軟件均能實(shí)現(xiàn)對照片的自動加密,成功率很高。此外,通過監(jiān)聽廣播實(shí)現(xiàn)文件自動加密的方法還可以推廣至音頻、視頻、文檔、短信等安全領(lǐng)域。隨著Android用戶的不斷增長,以及人們對個人隱私安全關(guān)注度的提升,我們相信透明加密助手軟件在未來有很高的實(shí)用價值,本文提出的自動加密方法在實(shí)際軟件開發(fā)中也有較好的應(yīng)用前景。
[1] 黃振濤,何暖,付安民,等.基于透明加密的移動終端數(shù)據(jù)防泄露系統(tǒng)[J].通信學(xué)報,2016,37(Z1):189-196.
[2] 王艷敏,李永忠,呂少偉.Android平臺下文件透明加密技術(shù)的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)技術(shù)與發(fā)展,2014,24(9):137-140.
[3] 周道明,錢魯鋒,王路路.透明加密技術(shù)研究[J].信息網(wǎng)絡(luò)安全,2011(12):54-56.
[4] 包佳敏,胡愛群.Android系統(tǒng)文件監(jiān)聽技術(shù)的研究[J].信息網(wǎng)絡(luò)安全,2014(3):46-51.
[5] 卿斯?jié)h.Android廣播機(jī)制安全性研究[J].電信科學(xué),2016(10):27-35.
[6] 尹京花,王華軍.基于Android開發(fā)的數(shù)據(jù)存儲[J].數(shù)字通信,2012,39(6):79-81.
[7] 張裔智,趙毅,湯小斌.MD5算法研究[J].計(jì)算機(jī)科學(xué),2008,35(7):295-297.
[8] 李云飛,柳青,郝林,等.一種有效的RSA算法改進(jìn)方案[J].計(jì)算機(jī)應(yīng)用,2010,30(9):2393-2397.
[9] 解雙建,原亮,謝方方.DES算法原理及其FPGA實(shí)現(xiàn)[J].計(jì)算機(jī)技術(shù)與發(fā)展,2011,21(7):158-160,164.
[10] 張金輝,國曉彪,符鑫.AES加密算法分析及其在信息安全中的應(yīng)用[J].信息網(wǎng)絡(luò)安全,2011(5):31-33.