Android應(yīng)用存儲安全與加固

目前移動領(lǐng)域已經(jīng)出現(xiàn)了相當(dāng)部分的安全問題脸狸,新的惡意軟件層出不窮,另一方面泥彤,企業(yè)對敏感數(shù)據(jù)保密性意識日益提高吟吝,作為移動開發(fā)者,有責(zé)任對最終用戶的隱私和安全承擔(dān)更多責(zé)任浙宜。

本文主要討論移動安全存儲策略粟瞬,設(shè)計了安全加固方案称开,實現(xiàn)了移動應(yīng)用逆向分析鳖轰、安全代碼自動注入等全流程的一鍵式加固工具,并進行了驗證焰轻。

1.移動數(shù)據(jù)存儲

Android平臺實現(xiàn)數(shù)據(jù)存儲的5種基本方式:

數(shù)據(jù)共享(SharedPreferences)

--內(nèi)部存儲(File)

--SQLite數(shù)據(jù)庫存儲

--外部存儲

--網(wǎng)絡(luò)存儲

本文主要討論前三種數(shù)據(jù)存儲類型辱志,實現(xiàn)了加密解密SDK狞膘,并實現(xiàn)對APP的安全存儲注入。首先我們來簡單討論下Android中數(shù)據(jù)存儲的位置——考慮數(shù)據(jù)安全挽封,有必要更改android應(yīng)用的存儲位置嗎已球?

在非root設(shè)備上,數(shù)據(jù)已可通過沙盒得到很好地安全保護(當(dāng)然辅愿,我們也不可以完全忽略設(shè)備存在內(nèi)核漏洞或虛擬機漏洞時可能發(fā)生的后果)智亮。“自定義存儲位置”也是一種設(shè)計方式点待,使破解者難以確定存儲的路徑阔蛉,并完全控制了存儲實現(xiàn),以進行加密和解密保護癞埠。但這樣做聋呢,失去了Android自身完善的特權(quán)分離機制(安全沙盒),將數(shù)據(jù)文件完全暴露在沙盒外遭笋,弊大于利坝冕,實際上意義不大。

因此這里仍選擇沙盒作為數(shù)據(jù)的存儲位置瓦呼,接下來主要討論對于root的設(shè)備喂窟,如何增強數(shù)據(jù)的安全性。在root設(shè)備上央串,需要通過數(shù)據(jù)擦除或數(shù)據(jù)加密磨澡,實現(xiàn)數(shù)據(jù)的安全存儲,降低數(shù)據(jù)暴露的可能性质和。

2.加密方案選擇

涉及到了加密稳摄,我們需要選擇一種加密算法,加密算法的選擇無窮無盡饲宿,本文采用AES加密算法厦酬,選擇128位秘鑰加密方式。以下是三種存儲類型在AES算法下的具體實現(xiàn)方式:

SharedPreferences存儲加密解密方式:對key和value同時加密瘫想,存儲類型都為String類型仗阅,數(shù)據(jù)讀取時根據(jù)需要進行類型轉(zhuǎn)換。

File文件存儲加密解密方式:對數(shù)據(jù)流進行加密解密国夜。

SQLite數(shù)據(jù)庫存儲加密解密方式:基于Sqlcipher進行實現(xiàn)减噪。

3.代碼注入方案設(shè)計

3.1注入方案比較

在”哪里”或者如何將我們提供的SDK注入到已有APP中,以及如何修改此APP中的實現(xiàn)车吹。這里注入的層面可以是:java字節(jié)碼(.class)或DEX字節(jié)碼(.smali)筹裕,二者分別對應(yīng)反編譯和反匯編過程。這里選擇后者作為注入方案窄驹,原因如下:

(1) smali語法定義明確朝卒,易于直接替換對象類型;

(2)在反編譯流程中乐埠,更直接扎运。

3.2 DEX字節(jié)碼

Dalvik虛擬機運行Dalvik字節(jié)碼,由java字節(jié)碼轉(zhuǎn)換而來饮戳,又稱為” Dalvik匯編語言”,是Dalvik指令集組成的代碼洞拨,Dalvik指令集是Dalvik虛擬機為自己專門設(shè)計的一套指令集扯罐。但嚴(yán)格說它不屬于正式語言,它的特點如下:

Dalvik指令在調(diào)用格式上模仿了C語言的調(diào)用約定烦衣;

--根據(jù)字節(jié)碼的大小與不同歹河,一些字節(jié)碼添加了名稱后綴以消除歧義掩浙;

32位常規(guī)類型的字節(jié)碼未添加任何后綴

64位常規(guī)類型的字節(jié)碼添加-wide后綴

特殊類型的字節(jié)碼根據(jù)具體類型添加后綴,如-boolean秸歧、-byte厨姚、-char、-void等

--根據(jù)字節(jié)碼的布局與選項不同键菱,一些字節(jié)碼添加了字節(jié)碼后綴以消除歧義谬墙,這些后綴通過在字節(jié)碼主名稱后添加斜杠(/)來分隔開;

--在指令集的描述中经备,寬度值中每隔字母表示寬度為4位拭抬。

我們來看一下它對方法的定義:

invoke-virtual {p0, v2, v3},

Landroid/content/Context;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;

move-result-object v1

這里調(diào)用了類android.content.Context的getSharedPreferences方法,其中p0寄存器存儲context實例侵蒙,方法的參數(shù)是兩個:一個是java.lang.String類型造虎,一個是int類型,兩個參數(shù)分別保存在寄存器v2和v3中纷闺,返回值是android.content.SharedPreferences類型算凿,并把返回值保存到v1寄存器中。

Dalvik字節(jié)碼中使用了寄存器保存變量和參數(shù)犁功。我們知道氓轰,Java虛擬機基于棧架構(gòu),程序需頻繁從棧上讀取或?qū)懭霐?shù)據(jù)波桩,會耗費CPU(指令分派戒努、內(nèi)存訪問次數(shù));Dalvik虛擬機基于寄存器架構(gòu)镐躲,數(shù)據(jù)訪問通過寄存器直接傳遞储玫。兩者都為每個線程維護一個PC計數(shù)器與調(diào)用棧,PC計數(shù)器以字節(jié)為單位記錄當(dāng)前運行位置距離方法開頭的偏移量萤皂。不同的是撒穷,Java棧記錄Java方法調(diào)用的活動記錄,以幀為單位保存線程的運行狀態(tài)裆熙,每調(diào)用一個方法就會分配新的棧幀壓入Java棧上端礼,方法返回則彈出并撤銷相應(yīng)的棧幀;而Dalvik棧維護一份寄存器表入录。

每個Dalvik寄存器都是32位蛤奥,對于大于這個長度的類型,用兩個相鄰寄存器存儲僚稿。寄存器被設(shè)計為兩種表示方法:v命名法和p命名法凡桥。具體請參考相關(guān)資料。

4.加固流程設(shè)計

App加固總流程如下:

apk反匯編 -> sdk注入 -> Smali文件掃描 -> 代碼修正 -> 正向匯編 -> apk簽名

5.加固流程實現(xiàn)

這里以SharedPreferences存儲為例蚀同,例舉SDK和代碼修正的實現(xiàn)方式缅刽。(其他步驟實現(xiàn)略)

5.1安全存儲SDK

SDK中提供了針對SharedPreferences存儲類型的加密解密方式啊掏,我們對外提供了一個SecureSharedPreferences類,它實現(xiàn)了android.content.SharedPreferences接口衰猛,并實現(xiàn)了接口所提供的各個方法迟蜜,將android.content.SharedPreferences類型實例作為參數(shù),傳遞給構(gòu)造方法啡省。當(dāng)讀取數(shù)據(jù)時娜睛,使用這個參數(shù)進行查詢并返回值,當(dāng)存儲數(shù)據(jù)時冕杠,在edit方法處微姊,返回一個實現(xiàn)android.content.SharedPreferences.Editor接口的類,進行數(shù)據(jù)的添加分预。

這樣的SDK設(shè)計使得代碼注入可行兢交,并只需要較少的修正量。

5.2 代碼修正

在調(diào)用SharedPreferences存儲時笼痹,某種實現(xiàn)方式可以是(java代碼):

SharedPreferences sp =context.getSharedPreferences("config", 0);

我們需要將其修正為調(diào)用我們提供的SDK方式來實例化sp對象配喳。DEX字節(jié)碼如下:

invoke-virtual {p0, v2, v3},

Landroid/content/Context;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;

我們首先將這個結(jié)果保存到一個寄存器下,這里可以使用v2或者v3寄存器凳干,它們分別對應(yīng)兩個類型的參數(shù):java.lang.String和int晴裹,而且之后不會再對它們進行使用,因而它們是可用的兩個寄存器救赐。這里我們選擇v3寄存器:

move-result-object v3

接下來新建一個SecureSharedPreferences對象涧团,并將它放到某寄存器下,這個寄存器需要是java中sp對象存儲的寄存器经磅,并且用這個寄存器的值進行SharedPreferences方法的調(diào)用泌绣,如v1寄存器:

new-instance v1,Lcom/…/SecureSharedPreferences;

繼而需要調(diào)用這個對象的構(gòu)造函數(shù),并把之前保存在v3寄存器中的值作為參數(shù)傳遞(SharedPreferences類型):

invoke-direct {v1, v3},

Lcom/…/SecureSharedPreferences;->(Landroid/content/SharedPreferences;)V

這樣就完成了修正過程预厌。

其他存儲類型以及調(diào)用方式的修正方式與以上類似阿迈,這里不再贅述。

6.驗證實踐

這里我們將整個流程所需的各個依賴包轧叽、庫文件苗沧、各個工具、代碼修正實現(xiàn)及我們提供的SDK集成到一起炭晒,形成一個一鍵式的加固工具(bat形式)待逞。以一個DEMO為例,DEMO中實現(xiàn)了以上三種存儲方式的數(shù)據(jù)存儲和讀取网严,其中存儲都以默認方式(明文)實現(xiàn)识樱,沒有進行安全加密。

將DEMO APK放到工作目錄下,啟動并得到加固后的安全APK(secure_demo.apk)牺荠,其中demo文件夾為中間過程產(chǎn)生的數(shù)據(jù)文件。

將它運行到一個root的Android測試機上驴一,并使用R.E.Explorer工具查看存儲休雌,可見數(shù)據(jù)已經(jīng)過了加密存儲,并能夠正確的解密并獲得原始數(shù)據(jù)肝断。SQLite數(shù)據(jù)庫對存儲本身進行了加密杈曲,因而加密后,通過工具(android內(nèi)置查看器或SQLite Expert Professional查看工具)已無法打開db文件胸懈。

7.總結(jié)與討論

本文主要討論了Android設(shè)備數(shù)據(jù)存儲安全問題担扑,重點關(guān)注于針對一個已有的、非安全存儲的移動應(yīng)用趣钱,如何將其加固為一個達到安全存儲結(jié)果的應(yīng)用涌献。

希望各位讀者們批評指正,并如若有更好的實踐或心得首有,及時交流和討論燕垃,十分感謝。最后附加了實現(xiàn)中幾點細節(jié)的討論:

(1)ART架構(gòu)

Android Art架構(gòu)和Dalvik架構(gòu)主要區(qū)別在于應(yīng)用的執(zhí)行是否使用即時編譯器井联,對于Art架構(gòu)來說卜壕,以軟件安裝即時性為犧牲,完成了代碼編譯烙常,以提高程序運行效率轴捎,而Dalvik架構(gòu)仍然需要即時編譯器的輔助。而無論是哪種架構(gòu)蚕脏,與本文中討論的加固方案應(yīng)該是不發(fā)生沖突的侦副。

(2)AES Seed

AES算法中是目前電子數(shù)據(jù)加密中被廣泛接受的方案,雖然密鑰是隨機生成的蝗锥,但仍然需要一個密鑰種子跃洛,而這個秘鑰種子的安全性也是決定整個加密算法安全性的關(guān)鍵。在一個移動應(yīng)用中终议,密鑰種子的生成算法可以以本地代碼方式提供(.so)汇竭,雖然so文件也不是絕對不可以被反編譯的,但是相對的會提高安全性穴张。此外细燎,谷歌還提出一種基于云存儲的方案:

“Google recently announced a cloud-based storagesolution for apps, so you could consider storing the key there. Or its seemsthat getting the key outside the device, like on a server, is better.”

(3)加密效率

AES算法處理過程復(fù)雜,導(dǎo)致大數(shù)據(jù)文件加密和解密效率不是很高皂甘,對于幾十兆的大文件加密玻驻,不是一個很好的選擇,因而企業(yè)在選擇大數(shù)據(jù)文件作為敏感數(shù)據(jù)保護目標(biāo)的話,需要對加密方式另行評估璧瞬。


感謝您讀完了本文户辫,如果您覺得文章內(nèi)容對您有用處,請贊賞支持下吧嗤锉。您的鼓勵是我極大地動力 :-)渔欢!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瘟忱,隨后出現(xiàn)的幾起案子奥额,更是在濱河造成了極大的恐慌,老刑警劉巖访诱,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垫挨,死亡現(xiàn)場離奇詭異,居然都是意外死亡触菜,警方通過查閱死者的電腦和手機九榔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玫氢,“玉大人帚屉,你說我怎么就攤上這事⊙浚” “怎么了攻旦?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長生逸。 經(jīng)常有香客問我牢屋,道長,這世上最難降的妖魔是什么槽袄? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任烙无,我火速辦了婚禮,結(jié)果婚禮上遍尺,老公的妹妹穿的比我還像新娘截酷。我一直安慰自己,他們只是感情好乾戏,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布迂苛。 她就那樣靜靜地躺著,像睡著了一般鼓择。 火紅的嫁衣襯著肌膚如雪三幻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天呐能,我揣著相機與錄音念搬,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛朗徊,可吹牛的內(nèi)容都是我干的首妖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼爷恳,長吁一口氣:“原來是場噩夢啊……” “哼悯搔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舌仍,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎通危,沒想到半個月后铸豁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡菊碟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年节芥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逆害。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡头镊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出魄幕,到底是詐尸還是另有隱情相艇,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布纯陨,位于F島的核電站坛芽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翼抠。R本人自食惡果不足惜咙轩,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阴颖。 院中可真熱鬧活喊,春花似錦、人聲如沸量愧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侠畔。三九已至结缚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間软棺,已是汗流浹背红竭。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人茵宪。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓最冰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稀火。 傳聞我的和親對象是個殘疾皇子暖哨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1. 什么是JVM? JVM本質(zhì)上就是一個軟件凰狞,是計算機硬件的一層軟件抽象篇裁,在這之上才能夠運行Java程序,JAV...
    小帝Ele閱讀 11,596評論 2 28
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理赡若,服務(wù)發(fā)現(xiàn)达布,斷路器,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,930評論 6 13
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,790評論 25 707
  • 接觸了RN之后逾冬,必不可免得要接觸界面之間跳轉(zhuǎn)之類的需求黍聂,而這一類需求的實現(xiàn)必須要使用到Navigator這個導(dǎo)航器...
    AnonyPer閱讀 1,169評論 0 0