記錄之前寫的一篇總結(jié)拗馒。
V1:V1是Android7.0之前的簽名方式,使用jar Signature方式對(duì)APK進(jìn)行簽名打包,jar Signature來(lái)自JDK茎毁。APK進(jìn)行簽名時(shí)會(huì)生成一個(gè)META-INF文件夾,里面有三個(gè)文件:MANIFEST.MF忱辅,CERT.RSA七蜘,CERT.SF,是用來(lái)記錄簽名信息的墙懂。
除了上述三個(gè)文件橡卤,其他的文件都會(huì)對(duì)文件內(nèi)容做一次SHA1算法,就是計(jì)算出文件的摘要信息,然后用Base64進(jìn)行編碼损搬。比如AndroidManifest.xml文件碧库,就會(huì)對(duì)它進(jìn)行編碼生成SHA-1值,把這個(gè)SHA-1值用Base64轉(zhuǎn)化網(wǎng)站轉(zhuǎn)化回去巧勤,就是MANIFEST.MF文件中記錄的條目值嵌灰。
因此,MANIFEST.MF中存儲(chǔ)的是:逐一遍歷里面的所有條目颅悉,如果是目錄就跳過(guò)沽瞭,如果是一個(gè)文件,就用SHA1(或者SHA256)消息摘要算法提取出該文件的摘要然后進(jìn)行BASE64編碼后剩瓶,作為“SHA1-Digest”屬性的值寫入到MANIFEST.MF文件中的一個(gè)塊中驹溃。該塊有一個(gè)“Name”屬性柒瓣,其值就是該文件在apk包中的路徑。
不再詳細(xì)累述吠架,CERT.SF文件做了什么工作:
1.計(jì)算這個(gè)MANIFEST.MF文件的整體SHA1值芙贫,再經(jīng)過(guò)BASE64編碼后,記錄在CERT.SF主屬性塊(在文件頭上)的“SHA1-Digest-Manifest”屬性值值下傍药。
2.逐條計(jì)算MANIFEST.MF文件中每一個(gè)塊的SHA1磺平,并經(jīng)過(guò)BASE64編碼后,記錄在CERT.SF中的同名塊中拐辽,屬性的名字是“SHA1-Digest”拣挪。
CERT.RSA是一個(gè)滿足PKCS7格式的文件:它會(huì)把之前生成的 CERT.SF文件,用私鑰計(jì)算出簽名, 然后將簽名以及包含公鑰信息的數(shù)字證書一同寫入CERT.RSA中保存俱诸。
總結(jié):V1加密簽名后菠劝,如果APK文件被篡改后,在APK安裝校驗(yàn)時(shí)睁搭,改變后的文件摘要信息與MANIFEST.MF的檢驗(yàn)信息不同赶诊,于是驗(yàn)證失敗,程序就不能成功安裝园骆。
如果你對(duì)更改的過(guò)的文件相應(yīng)的算出新的摘要值舔痪,然后更改MANIFEST.MF文件里面對(duì)應(yīng)的屬性值,那么必定與CERT.SF文件中算出的摘要值不一樣锌唾,照樣驗(yàn)證失敗锄码。
如果不死心繼續(xù)計(jì)算MANIFEST.MF的摘要值,相應(yīng)的更改CERT.SF里面的值晌涕,那么數(shù)字簽名值必定與CERT.RSA文件中記錄的不一樣滋捶,還是失敗。
所以余黎,重新打包后的應(yīng)用程序能再Android設(shè)備上安裝重窟,必須對(duì)其進(jìn)行重簽名。
V2:Android7.0推出了V2簽名方式驯耻,使用Full Apk Signature方式對(duì)APK進(jìn)行簽名打包亲族。
經(jīng)過(guò)對(duì)V1的詳細(xì)介紹,V2就簡(jiǎn)單明了了可缚。V1是驗(yàn)證單個(gè)的ZIP條目,而V2則是驗(yàn)證壓縮文件的所有字節(jié)碼斋枢。因此帘靡,在簽名完成后無(wú)法再更改(包括zipalign)。因此瓤帚,現(xiàn)在在編譯過(guò)程中描姚,壓縮涩赢、調(diào)整和簽署合并成一步完成。好處是轩勘,更安全而且新的簽名可縮短在設(shè)備上進(jìn)行驗(yàn)證的時(shí)間(不需要費(fèi)時(shí)地解壓縮然后驗(yàn)證)筒扒,從而加快應(yīng)用安裝速度。當(dāng)然只在Android7.0以上的手機(jī)才會(huì)使用這種驗(yàn)證方式绊寻。
總結(jié):
選擇V1還是V2花墩?
只選擇V1,還是依照舊的簽名方式澄步,不會(huì)有任何影響冰蘑,只是在Android7.0以上的手機(jī)上不會(huì)使用更安全的驗(yàn)證方式。
只選擇V2村缸,在Android7.0以上的手機(jī)沒問題祠肥,但是由于7.0以下的系統(tǒng)沒有這種新的驗(yàn)證方式,因此會(huì)提示未安裝梯皿。
同時(shí)選擇V1和V2仇箱,在Android7.0以下的手機(jī)會(huì)使用V1驗(yàn)證,7.0以上的會(huì)使用V2方式驗(yàn)證东羹,因此都沒問題工碾。
新的問題(多渠道打包)
由于Android市場(chǎng)眾多,因此需要標(biāo)記不同的渠道包百姓。
目前使用的方案是:使用V1簽名方式渊额,美團(tuán)Python腳本批量打包,它的原理就是生成一個(gè)全新的文件垒拢,把APK進(jìn)行解壓遍歷復(fù)制進(jìn)去旬迹,復(fù)制中通過(guò)在META-INF目錄下添加空文件,用空文件的名稱來(lái)作為渠道的唯一標(biāo)識(shí)求类,之前在META-INF下添加文件是不需要重新簽名應(yīng)用的奔垦,因此批量打出的包在Android上是可以校驗(yàn)通過(guò)的。
但是如果使用的V2方式尸疆,在新的應(yīng)用簽名方案下META-INF已經(jīng)被列入了保護(hù)區(qū)了椿猎,那么Python腳本批量打出的包就會(huì)造成Android7.0上校驗(yàn)不通過(guò),這便是之前我們遇到的問題寿弱。
雖然只使用V1簽名驗(yàn)證不會(huì)影響什么犯眠,但V2是谷歌爸爸推薦的簽名方式,肯定是要慢慢用起來(lái)的症革,一路高歌走向安全規(guī)范化的道路筐咧。
美團(tuán)推出了針對(duì)V2的新一套批量打包方式,并生成了插件,可以使用Gradle快速集成量蕊。
Walle(瓦力)https://github.com/Meituan-Dianping/walle
可擴(kuò)展的APK Signature Scheme v2 Block
V2的簽名信息是以ID(0x7109871a)的ID-value來(lái)保存在這個(gè)區(qū)塊中铺罢,通過(guò)Android源代碼可以看出Android是通過(guò)查找ID為 APK_SIGNATURE_SCHEME_V2_BLOCK_ID = 0x7109871a 的ID-value,來(lái)獲取APK Signature Scheme v2 Block残炮,對(duì)這個(gè)區(qū)塊中其他的ID-value選擇了忽略韭赘。
因此美團(tuán)是通過(guò)提供一個(gè)自定義的ID-value并寫入該區(qū)域,從而為快速生成渠道包服務(wù)势就,每打一個(gè)渠道包只需復(fù)制一個(gè)APK泉瞻,然后在APK中添加一個(gè)ID-value即可。
所以蛋勺,我們可以考慮采用這用新的方式來(lái)打渠道包了瓦灶。
參考鏈接:
https://tech.meituan.com/android-apk-v2-signature-scheme.html
http://blog.csdn.net/u011904605/article/details/52058971
http://www.reibang.com/p/a27783a713f2
http://www.reibang.com/p/e1e2fd05bb62
關(guān)于上次分享的APK加殼概念:
一、什么是加殼抱完?
加殼是在二進(jìn)制的程序中植入一段代碼贼陶,在運(yùn)行的時(shí)候優(yōu)先取得程序的控制權(quán),做一些額外的工作巧娱。大多數(shù)病毒就是基于此原理碉怔。是應(yīng)用加固的一種手法對(duì)原始二進(jìn)制原文進(jìn)行加密/隱藏/混淆。
1禁添、需要加密的Apk(源Apk)
2撮胧、殼程序Apk(負(fù)責(zé)解密Apk工作)
3、加密工具(將源Apk進(jìn)行加密和殼Dex合并成新的Dex)
加殼程序就是把要加殼的apk放入解殼程序的dex文件中老翘。
解殼程序是最后替代我們apk安裝到手機(jī)中運(yùn)行的程序芹啥。它在執(zhí)行中從自己的dex中釋放出我們apk程序。
二铺峭、加殼作用
加殼的程序可以有效阻止對(duì)程序的反匯編分析墓怀,其實(shí)就是魚目混珠。
參考鏈接: