劉培鶴 閆翔宇 何文才, 繆浩健
1(北京電子科技學(xué)院通信工程系 北京 100070) 2(西安電子科技大學(xué)通信工程學(xué)院 陜西 西安 710071)
現(xiàn)代社會,智能手機(jī)已經(jīng)成為人們生活的一部分,手機(jī)存儲著個人信息、圖片、音樂、工作日程等。除了系統(tǒng)原生的軟件程序,種類繁多的第三方應(yīng)用同樣占據(jù)著人們的大部分時間如微信、京東、支付寶等,除此之外自助洗衣、外賣購物等各種便利服務(wù)同樣需要手機(jī)客戶端的支撐。用戶不可避免地要將身份證號、電話號碼、通信地址等隱私信息交給應(yīng)用程序管理。2016年12月10日,一則京東數(shù)據(jù)疑似外泄的新聞引起人們的關(guān)注,據(jù)報道泄露的數(shù)據(jù)涉及數(shù)千萬用戶[1]。由此可見,應(yīng)用程序在為用戶提供便利服務(wù)的同時擔(dān)負(fù)著保護(hù)用戶數(shù)據(jù)安全的重任。
安裝在手機(jī)上的客戶端是數(shù)據(jù)產(chǎn)生和存儲的第一個場所,如何保護(hù)客戶端的隱私數(shù)據(jù)顯得異常重要。Android開發(fā)相對于iOS開發(fā)門檻底,國內(nèi)應(yīng)用市場混亂,這也使得Android客戶端隱私數(shù)據(jù)的保護(hù)問題更為嚴(yán)峻。大部分開發(fā)工作在應(yīng)用層進(jìn)行,使用Java語言。Java語言反編譯后極易閱讀,雖然大多應(yīng)用會通過ProGuard進(jìn)行混淆,但字符串、數(shù)組等內(nèi)容卻會暴露給攻擊者[2]。目前主流的加密算法如AES、DES等算法都已公開,Java語言可以直接調(diào)用集成好的算法庫。對于攻擊者而言,只要找到密鑰,便可輕松獲取加密信息。因此安全存儲密鑰是Android客戶端隱私數(shù)據(jù)保護(hù)的重中之重。
本文將秘密共享的思想引入到Android客戶端開發(fā)中,提出了一種密鑰分存方案。該方案簡單,只涉及應(yīng)用層實現(xiàn),不存儲實際密鑰,可以有效提高客戶端數(shù)據(jù)存儲的安全性。
Android作為一種開源的操作系統(tǒng),其安全性受到國內(nèi)外專家學(xué)者的廣泛關(guān)注,但關(guān)于密鑰存儲方向的研究并不是很多。
硬件廠商建議通過在手機(jī)中設(shè)立安全存儲區(qū)的方式解決。在硬件層建立兩個執(zhí)行環(huán)境,如圖1所示,一個是正常區(qū)域,用于運(yùn)行Android操作系統(tǒng),另一個作為特殊的安全空間,將密鑰、安全證書等內(nèi)容存放在安全空間中。2012年ARM處理器宣稱已經(jīng)擁有安全存儲區(qū)的技術(shù),并投入生產(chǎn)[3]。但是,安全存儲區(qū)的方案并不能提供安全保障,因為兩個存儲區(qū)之間是需要信息交互的,Android系統(tǒng)區(qū)必須依賴安全存儲區(qū)才能正常運(yùn)行。此外不同廠商生產(chǎn)的手機(jī),甚至同一廠商生產(chǎn)的不同版本,安全存儲區(qū)的設(shè)定都不完全相同,這就限制了該方案的使用范圍。
圖1 安全存儲區(qū)的方案
2013年7月,Android 4.3版本發(fā)布,在這個新的版本中增加了一個用于存儲密鑰的程序KeyStore。KeyStore可以存儲密鑰[4],并且只能被創(chuàng)建它的應(yīng)用程序訪問。但是KeyStore的設(shè)計初衷是用來存儲證書的,因此對稱加密算法的密鑰如AES并不能直接存儲在這里。此外,在較低版本的Android系統(tǒng)中,也無法使用這種密鑰存儲方式。
2014年Cooijmans等[5]提出了一種方案,他們利用Java平臺的輕量級密碼包bouncy castle進(jìn)行密鑰存儲。這種方式的優(yōu)勢是不依賴安全存儲區(qū)域和手機(jī)版本,可以運(yùn)用在所有Android系統(tǒng)中。但該方案依舊只是將用戶提供的密鑰直接進(jìn)行加密存儲,密鑰的存儲相對集中,只要泄露或破壞,存儲的內(nèi)容就會失效。
2015年Makan等[6]在《安全攻防實踐》一書中介紹了一種基于口令的加密方案(PBE)。這種方案不直接生成密鑰,而是讓用戶用口令經(jīng)過計算和迭代推導(dǎo)出密鑰,從而減少了密鑰暴露的風(fēng)險。但對于口令的安全存儲,并沒有給出好的解決方案,攻擊者獲得了口令就找到了攻破的入口。
2016年劉超[7]提出了一種基于Android的靜態(tài)密鑰存儲的方案。他將密鑰直接分割成幾段,將各段分別在gradle配置、Java編碼、字符串拼接、string.xml等位置。該方法在一定程序上提高了逆向的難度,保障了密鑰的安全性。但是Android系統(tǒng)具有開放性,用戶操作的權(quán)限很高,尤其對于擁有Root權(quán)限的用戶。用戶在使用過程中很可能誤刪其中的一段或多段密鑰,這樣就會導(dǎo)致加解密失敗,應(yīng)用程序不能正常使用,降低了穩(wěn)定性。
綜上,有的方案受手機(jī)類型和手機(jī)版本的限制,不具有通用性;有的密鑰存儲的位置過于單一,一旦密鑰暴露,密文就面臨泄密和失效的危險;有的密鑰的魯棒性低,無法承受惡意攻擊或意外損壞。而對于一般的應(yīng)用開發(fā),必須匹配市面上的大多數(shù)Android版本和不同廠商,同時應(yīng)具備高效、穩(wěn)定等特點(diǎn)。本文提出了一種應(yīng)用于Java層的動態(tài)密鑰分存方案。該方案效率高,易于實現(xiàn),不受手機(jī)版本限制,可以有效抵御Android客戶端密鑰被竊取和篡改的風(fēng)險,提高了數(shù)據(jù)存儲的安全性。
秘密共享[8]是一種保證信息安全和數(shù)據(jù)保密的密鑰管理手段。它通過某種方式將密鑰拆分,交給不同的參與者共同管理。參與者自己無法獲得秘密信息,只有當(dāng)若干個參與者共同協(xié)作時,才可以恢復(fù)出密鑰的全部信息,然后獲得密文。秘密共享技術(shù)通過分存的方式降低了秘密信息泄露的風(fēng)險,同時也提高了密鑰存儲的魯棒性,少量共享信息的竊取和篡改,不會影響整體秘密信息的安全。
門限法是Shamir[8]提出的一個用于指導(dǎo)共享信息生成和分發(fā)的方案,用(m,n)表示。m表示恢復(fù)密鑰所需的最少分存信息份數(shù),n表示生成的秘密信息的總份數(shù),其中n=2m-1。當(dāng)多于m個共享信息共同協(xié)作時,可以獲得真正的密鑰。小于或等于m-1個共享信息丟失或損壞時,不影響最終密鑰的恢復(fù)。
拉格朗日插值多項式是一種簡單的秘密共享方案。假設(shè)要在n個人中共享密鑰M,使得他們中任何m(m≤n)個人通過共同協(xié)作獲得密鑰,任意小于m個人無法獲得密鑰,可以通過下面的步驟實現(xiàn):
1) 生成隨機(jī)質(zhì)數(shù)p。
2) 生成m-1個隨機(jī)整數(shù)R1,R2,…,Rm-1,其中每一個數(shù)都比p小。
3) 使用下列式子將F(x)定義成有限域上的多項式。
F(x)=(R1×xm-1+R2×xm-2+…+Rm-1×
x+M)modp
(1)
4) 通過x的變化生成不同的F(x),將(p,xi,F(xi))交給n個密鑰共享者,其中i對應(yīng)共享者的號碼。
5) 摧毀R1,R2,…,Rm-1和M。此時密鑰M已被銷毀。
6) 每位密鑰共享者可以根據(jù)自己存儲的信息寫出一個線性方程:
F(xi)=(C1×xm-1+C2×xm-2+…+Cm-1×
x+M)modp
(2)
該方案有m個未知數(shù),分別為C1,C2,…,Cm-1和M,因此需要m個方程來求解,即m個密鑰共享者協(xié)作可得到M,從而獲得密文。
高級加密標(biāo)準(zhǔn)[9]AES(Advanced Encryption Standard)是美國國家標(biāo)準(zhǔn)技術(shù)研究所在2001年發(fā)布的一種對稱分組密碼算法。假設(shè)有一臺可以在一秒內(nèi)破解DES密碼的機(jī)器,則需要花費(fèi)大約149億年才能破解128位的AES密碼。因此可以認(rèn)為暴力破解不可實現(xiàn)。本方案采用AES加密模式中的密碼分組鏈接模式CBC(Cipher Block Chaining),如圖2所示。
圖2 AES-CBC加密模型
這是一種循環(huán)模式,整個加密過程始于一個隨機(jī)生成數(shù)IV。首先將明文分成若干個加密塊,IV長度與加密塊長度保持相同。加密前,明文的第一塊內(nèi)容與IV先進(jìn)行“異或”操作再進(jìn)行加密處理,這樣對明文起到了掩飾作用。之后將前一段的密文作為IV和后一段的明文進(jìn)行“異或”,“異或”后的內(nèi)容進(jìn)行再加密處理,如此反復(fù)循環(huán)。這種方案與默認(rèn)的ECB模式相比,降低了破獲的難度,幾乎不能從密文中猜測出明文信息。
基于口令的加密PBE(Password Based Encryption)是Java加密擴(kuò)展中的一部分,該方案由用戶提供的口令去創(chuàng)建密鑰。如圖3所示,密鑰的生成由兩部分內(nèi)容決定:(1) 口令(Password),用戶可讀的字符串或數(shù)字。(2) 鹽(Salt),一個隨機(jī)信息。
圖3 基于口令的密鑰生成方案
PBE已經(jīng)包含在Android SDK中,可以直接利用。
3.1節(jié)中密鑰的生成的關(guān)鍵在于口令,如果攻擊者找到了口令即為找到了攻破的入口。本方案通過拉格朗日插值多項式將口令進(jìn)行分存處理,使得不再需要存儲口令的內(nèi)容。具體步驟如下:
1) 基于Android存儲特點(diǎn)和門限法的指導(dǎo),方案選擇(m,n)=(4,7)。共生成7個秘密共享項,任意大于等于4個可以協(xié)作恢復(fù)口令,小于4個無法恢復(fù)。
2) 通過SecureRandom類生成隨機(jī)數(shù)。方案通過該類生成數(shù)據(jù),分別為參數(shù)R1、R2、R3、R4,口令M和未知數(shù)x1、x2、x3、x4、x5、x6、x7。
3) 將參數(shù)和未知數(shù)代入如下方程:
F(x)=R1×x3+R2×x2+R3×x+M
(3)
可以得到對應(yīng)的F(xi)。
4) 存儲(xi,F(xi)),丟棄R和M。
5) 解密時,將m對(xi,F(xi))代入式(3),解方程組即可得到口令M。
Android應(yīng)用常規(guī)的存儲方式有三大類:文件存儲、SharedPreferences存儲和SQLite存儲。除此之外Java硬編碼、String.xml 、gradle等也可以進(jìn)行簡單的字符串和數(shù)組靜態(tài)存儲。Setting.System常用來存儲關(guān)于設(shè)備屬性的設(shè)置,應(yīng)用軟件也可以進(jìn)行少量數(shù)據(jù)的存儲。但在Android 6.0以上,需要動態(tài)申請權(quán)限。
本方案對存儲方式的要求是動態(tài)、持久化。考慮到安全性和簡易性,方案選擇的存儲位置為SharedPreference、文件存儲和Setting.System。
方案中共享信息共為7份,只要4份以上的共享信息便可以恢復(fù)出原始的口令。采用的存儲方式是文件存儲兩份,Setting.System存儲兩份,SharedPreference存儲三份。
本方案功能的實現(xiàn)主要由三個模塊組成,各部分內(nèi)容如圖4所示。
圖4 方案功能模塊劃分
1) PBEGenerateKey模塊負(fù)責(zé)管理密鑰和文件的加解密。為提高安全性,方案采用的是256位密鑰的AES-CBC加密方案。為防止暴力攻擊建議推導(dǎo)密鑰的時間大于100 ms,使用的迭代次數(shù)為10 000次。為提高效率IV和Salt的生成方式用random類。
2) SecurePassword模塊負(fù)責(zé)口令的生成與分發(fā)。該模塊是方案的關(guān)鍵,因此,隨機(jī)數(shù)的生成均使用SecureRandom類。SecureRandom類是安全的偽隨機(jī)數(shù)生成方案,多在密鑰生成中,但需要注意一定不要用偽隨機(jī)數(shù)生成數(shù)設(shè)定種子,否則安全性將大大降低。
3) Equation模塊負(fù)責(zé)口令的恢復(fù)。該模塊的主要功能是利用線性代數(shù)解四元一次方程組,應(yīng)注意計算機(jī)數(shù)組存取時會進(jìn)行舍取,為滿足計算精度,所有的參數(shù)都設(shè)定在正整數(shù)范圍內(nèi)。
4) 口令恢復(fù)時分存信息的獲取采用輪循機(jī)制,先讀取4個分存信息,如果解密失敗,則證明部分分存信息遭到破壞,再繼續(xù)獲取其他分存信息,直到正確恢復(fù)密文為止。
5) IV和Salt對密文的恢復(fù)至關(guān)重要,應(yīng)與密文或口令存放在一次,本方案存儲在SharedPreference中。
6) 為保證安全性,口令、IV和Salt應(yīng)經(jīng)常更換,本方案根據(jù)使用次數(shù)進(jìn)行限定。
方案的主要功能模塊為三個Java類,大小僅為14.5 KB,不會對原工程增加太大的開銷。選取10個大小不同的文件進(jìn)行加解密,通過輸出LOG日志的方式來進(jìn)行時間性能測試。
集成開發(fā)環(huán)境使用的是Android Studio 版本參數(shù)如表1所示。
表1 集成開發(fā)環(huán)境
測試機(jī)使用的是紅米手機(jī),版本參數(shù)如表2所示。
表2 測試手機(jī)版本參數(shù)
測試結(jié)果如表3所示。
表3 文件加解密測試數(shù)據(jù)
口令操作時間為將口令轉(zhuǎn)化為共享信息,分存,再由分存信息轉(zhuǎn)化為口令的時間。由表3可知,口令的操作時間的均值為0.037 s,僅占總時間的2.70%。由此可得,該密鑰分存方案不會過多影響加解密的性能。
將10組數(shù)據(jù)中的加解密總時間轉(zhuǎn)化為折線圖,如圖5所示。
圖5 文件加解密總時間折線圖
由于文件內(nèi)容格式等原因,加解密時間會受到影響,但總體而言,隨著文件大小的增加,加解密時間也隨之增長。這是因為AES算法是一種分組密碼,加解密過程是將文件內(nèi)容分割成塊進(jìn)行循環(huán)處理。因此,隨著文件大小的增加,加解密時間也隨之增加。但時間增加的量級并不大。
4.2.1參數(shù)設(shè)置的安全性
方案中使用的口令、R1、R2、R3、R4,以及xi、F(xi)均用int型表示,Java中int的存儲范圍是固定的,在[-2 147 483 648,2 147 483 647]之間。顯然,數(shù)據(jù)越大,方案的安全性越高。為提高安全性且防止數(shù)據(jù)大小越界,對各類數(shù)據(jù)隨機(jī)生成的范圍進(jìn)行限定,如表4所示。
表4 數(shù)據(jù)生成范圍
所有的數(shù)據(jù)都在int的存儲范圍內(nèi),不會發(fā)生溢出。
M、R1、R2、R3、R4以及xi都由未設(shè)定種子的SecureRandom類生成,最大程度地保證了生成數(shù)據(jù)的隨機(jī)性,增加了密鑰被暴力攻擊的難度。
4.2.2密鑰的安全性
本方案并沒有直接生成密鑰,而是通過基于口令的密鑰生成算法生成密鑰,這本身就增加了暴力攻擊的難度。方案中的口令又是通過SecureRandom類生成的9位正隨機(jī)數(shù),不直接存儲隨機(jī)數(shù)而是存儲共享信息,攻擊者不能通過手機(jī)的存儲信息找到密鑰。
共享信息的存儲采用的方式是SharedPreference存儲三份、文件和Setting.System各存儲兩份。口令重組的條件至少需要四份共享信息,因此即使攻擊者找到了一個口令存儲位置仍無法計算出口令,保障了安全性。同時,Android手機(jī)的信息存儲無法做到絕對安全,在Root的設(shè)備上,所有目錄下的內(nèi)容都可能發(fā)生更改和誤刪。本方案將口令分存信息分散地存儲在手機(jī)的多個位置,口令的重建不需要所有的分存信息,如果其中一個位置的內(nèi)容受到攻擊,另外兩個位置的分存信息仍大于門限值,可以繼續(xù)還原出原始口令。這大大提高了Android手機(jī)上密鑰存儲的魯棒性。
本文創(chuàng)新性地將密鑰分存的思想引入到了Android客戶端的開發(fā)中,利用門限法及拉格朗日插值多項式提出了一種Java層的密鑰分存方案。該方案提高了客戶端密鑰存儲的安全性和魯棒性,方案在低性能損耗下大幅度提高了客戶端數(shù)據(jù)存儲的安全,可以被應(yīng)用于商用應(yīng)用軟件的開發(fā)中。
方案采用的是256位AES-CBC加密方案,口令隨機(jī)數(shù)的生成均使用安全的隨機(jī)數(shù)生成類SecureRandom生成,密鑰由10 000次迭代,最大程度保障了密鑰的安全性。為提高加解密效率,可在滿足安全性需求的情況下,選擇合適的參數(shù)配置。為減少方案的復(fù)雜度,所有內(nèi)容均在應(yīng)用層執(zhí)行操作。進(jìn)一步提高安全性,可將部分口令分存信息編譯到SO文件中,增加反編譯的難度。方案安全性建立在分存信息存儲位置的安全性上,可以考慮對SharedPreference加密等方式進(jìn)行安全提升。分存信息生成的總量也將影響方程的執(zhí)行效率。以上問題,將在未來的工作中進(jìn)行進(jìn)一步研究。
[1] 一本財經(jīng).京東數(shù)據(jù)疑似外泄:超過12個G涉及數(shù)千萬用戶[EB/OL].(2016-12-10).[2016-12-12].http://dy.163.com/v2/article/detail/C7V45B7A05199F1P.html.
[2] Shabtai A,Fledel Y,Kanonov U,et al.Google Android:A comprehensive security assessment[J].IEEE Security & Privacy,2010,8(2):35-44.
[3] Mick J.ARM to bake on-die security into next gen Smartphone,tablet,PC cores[EB/OL].(2012-4-3).[2016-10-9].http://www.dailytech.com/ARM+to+Bake+OnDie+Security+Into+Next+Gen+Smartphone+Tablet+PC+Cores/article24372.htm.
[4] Hay R,Dayan A.Android KeyStore stack buffer overflow-CVE-2014-3100[OL].2014.http://www.securityfocus.com/bid/68152.
[5] Cooijmans T,Ruiter J D,Poll E.Analysis of Secure Key Storage Solutions on Android[C]//The,ACM Workshop.ACM,2014:11-20.
[6] Makan Keith,Alexander-Bown Scott.Android安全攻防實踐[M].崔孝晨,武曉音,譯.北京:電子工業(yè)出版社,2015.
[7] 劉超.Android中保存靜態(tài)密鑰實踐[EB/OL].(2016-07-25).[2016-12-9].http://blog.csdn.net/qq_23547831.
[8] Shamir A.How to share a secret[J].Communications of ACM,1979,24(11):612-613.
[9] Ferguson N,Schroeppel R,Whiting D.A simple algebraic representation of Rijndael[C]//Proceedings of Selected Areas in Cryptography,2001.Toronto:Springer,2001.