參考:
http://tech.meituan.com/android-apk-v2-signature-scheme.html
http://www.reibang.com/p/a6e7a01c6cad
APK signature scheme v2(官網(wǎng)如是說)
Android 7.0 引入一項(xiàng)新的應(yīng)用簽名方案 APK Signature Scheme v2买鸽,它能提供更快的應(yīng)用安裝時(shí)間和更多針對(duì)未授權(quán) APK 文件更改的保護(hù)。在默認(rèn)情況下雷绢,Android Studio 2.2 和 Android Plugin for Gradle 2.2 會(huì)使用 APK Signature Scheme v2 和傳統(tǒng)簽名方案來簽署您的應(yīng)用摧茴。
雖然我們建議您對(duì)您的應(yīng)用采用 APK Signature Scheme v2藏否,但這項(xiàng)新方案并非強(qiáng)制性的鞭衩。如果您的應(yīng)用在使用 APK Signature Scheme v2 時(shí)不能正確開發(fā)门驾,您可以停用這項(xiàng)新方案射赛。禁用過程會(huì)導(dǎo)致 Android Studio 2.2 和 Android Plugin for Gradle 2.2 僅使用傳統(tǒng)簽名方案來簽署您的應(yīng)用。要僅用傳統(tǒng)方案簽署奶是,打開模塊級(jí) build.gradle
文件楣责,然后將行 v2SigningEnabled false
添加到您的版本簽名配置中:
android {
...
defaultConfig { ... }
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
v2SigningEnabled false
}
}
}
注意:如果您使用 APK Signature Scheme v2 簽署您的應(yīng)用竣灌,并對(duì)應(yīng)用進(jìn)行了進(jìn)一步更改,則應(yīng)用的簽名將無效秆麸。出于這個(gè)原因初嘹,請(qǐng)?jiān)谑褂?APK Signature Scheme v2 簽署您的應(yīng)用之前、而非之后使用 zipalign
等工具沮趣。
如需了解詳細(xì)信息屯烦,請(qǐng)閱讀相關(guān)的 Android Studio 文檔,這些文檔介紹了如何在 Android Studio 中簽署應(yīng)用以及如何使用 Android Plugin for Gradle 為簽署應(yīng)用配置構(gòu)建文件房铭。
android studio2.3的正式版之后驻龟,正式啟用了V2的簽名方式
使用v2方式打包,7.0以下安裝失敗缸匪。
使用v1方式打包翁狐,7.0以及7.0以下的版本都沒問題。
結(jié)論:?jiǎn)为?dú)使用V2簽名的apk是不能在小于7.0的手機(jī)上安裝的豪嗽,會(huì)出現(xiàn)簽名證書找不到的情況谴蔑,為了防止出現(xiàn)這種情況,AS使用了可以同時(shí)選擇兩種簽名方式
即:7.0以下使用V1的簽名方式龟梦,7.0以后的就使用V2的簽名方式
APK文件格式
apk 本身是個(gè) zip 格式, 格式可以參考http://blog.sina.com.cn/s/blog_4c3591bd0100zzm6.html.
新的簽名方案會(huì)在ZIP文件格式的 Central Directory 區(qū)塊所在文件位置的前面添加一個(gè)APK Signing Block區(qū)塊隐锭,下面按照Z(yǔ)IP文件的格式來分析新應(yīng)用簽名方案簽名后的APK包。
整個(gè)APK(ZIP文件格式)會(huì)被分為以下四個(gè)區(qū)塊:
Contents of ZIP entries(from offset 0 until the start of APK Signing Block)
APK Signing Block
ZIP Central Directory
ZIP End of Central Directory
新應(yīng)用簽名方案的簽名信息會(huì)被保存在區(qū)塊2(APK Signing Block)中计贰, 而區(qū)塊1(Contents of ZIP entries)钦睡、區(qū)塊3(ZIP Central Directory)、區(qū)塊4(ZIP End of Central Directory)是受保護(hù)的躁倒,在簽名后任何對(duì)區(qū)塊1荞怒、3、4的修改都逃不過新的應(yīng)用簽名方案的檢查秧秉。
這樣的話褐桌,之前的美團(tuán)打包方案就會(huì)有問題。
http://www.reibang.com/p/ef186125dac4
新的應(yīng)用簽名方案下META-INF已經(jīng)被列入了保護(hù)區(qū)了象迎,向META-INF添加空文件的方案會(huì)對(duì)區(qū)塊1荧嵌、3、4都會(huì)有影響砾淌,新應(yīng)用簽名方案簽署的應(yīng)用經(jīng)過我們舊的生成渠道包方案處理后啦撮,在安裝時(shí)會(huì)報(bào)以下錯(cuò)誤:
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES:
Failed to collect certificates from base.apk: META-INF/CERT.SF indicates base.apk is signed using APK Signature Scheme v2,
but no such signature was found. Signature stripped?]
多渠道打包解決方案
1 、往APK中添加ZIP Comment
這種方法是根據(jù)zip格式核心目錄的內(nèi)容注釋(Comment)做處理
End of central directory record
Offset Bytes Description
0 4 End of central directory signature = 0x06054b50 核心目錄結(jié)束標(biāo)記(0x06054b50)
4 2 Number of this disk 當(dāng)前磁盤編號(hào)
6 2 Disk where central directory starts 核心目錄開始位置的磁盤編號(hào)
8 2 Number of central directory records on this disk 該磁盤上所記錄的核心目錄數(shù)量
10 2 Total number of central directory records 該磁盤上所記錄的核心目錄數(shù)量
12 4 Size of central directory (bytes) 核心目錄的大小
16 4 Offset of start of central directory, relative to start of archive 核心目錄開始位置相對(duì)于archive開始的位移
20 2 Comment length (n) 注釋長(zhǎng)度 (n)
22 n Comment 注釋內(nèi)容
apk 默認(rèn)情況下沒有comment汪厨,所以 comment length的short 兩個(gè)字節(jié)為 0赃春,我們需要把這個(gè)值修改為我們的comment的長(zhǎng)度,然后把comment追加到后邊即可劫乱。
在gradle 中通過如下方式 disable scheme v2
signingConfigs {
release {
v2SigningEnabled false
}
}
2 织中、美團(tuán)第一代打包工具walle
通過上圖可以看出新的應(yīng)用簽名方案的驗(yàn)證過程:
尋找APK Signing Block锥涕,如果能夠找到,則進(jìn)行驗(yàn)證狭吼,驗(yàn)證成功則繼續(xù)進(jìn)行安裝站楚,如果失敗了則終止安裝
如果未找到APK Signing Block,則執(zhí)行原來的簽名驗(yàn)證機(jī)制搏嗡,也是驗(yàn)證成功則繼續(xù)進(jìn)行安裝,如果失敗了則終止安裝
美團(tuán)通過在APK Signing Block中擴(kuò)展ID-VALUE來實(shí)現(xiàn)渠道包拉一。
因?yàn)樵谠创a當(dāng)中采盒,只存在一個(gè)ID-VALUE的判斷
if (id == APK_SIGNATURE_SCHEME_V2_BLOCK_ID) {return getByteBuffer(pairs, len - 4);}
而這個(gè)區(qū)域的其它 ID-VALUE 是被忽略的。
將渠道號(hào)放到里面蔚润,打包的時(shí)候就能繞過驗(yàn)證磅氨。
到這里為止一個(gè)新的渠道包生成方案逐步清晰了起來,下面是新一代渠道包生成工具的描述:
對(duì)新的應(yīng)用簽名方案生成的APK包中的ID-value進(jìn)行擴(kuò)展嫡纠,提供自定義ID-value(渠道信息)烦租,并保存在APK中
而APK在安裝過程中進(jìn)行的簽名校驗(yàn),是忽略我們添加的這個(gè)ID-value的除盏,這樣就能正常安裝了
在App運(yùn)行階段叉橱,可以通過ZIP的EOCD(End of central directory)、Central directory等結(jié)構(gòu)中的信息(會(huì)涉及ZIP格式的相關(guān)知識(shí)者蠕,這里不做展開描述)找到我們自己添加的ID-value窃祝,從而實(shí)現(xiàn)獲取渠道信息的功能