問題
Android打包apk時需要使用開發(fā)者證書進行簽名,以前是keystore文件,現(xiàn)在是jks文件。如果使用不同的證書進行簽名钧汹,相同包名的apk是無法覆蓋安裝進行升級的。那么录择,如果證書有效期到了怎么辦拔莱?如果證書信息創(chuàng)建的時候都是瞎寫的,現(xiàn)在想改了怎么辦糊肠?應(yīng)用的開發(fā)商換了辨宠,為了安全,新的開發(fā)商需要使用自己的證書怎么辦货裹?Google在Android9的時代就推出了v3版的簽名方式嗤形,支持更換簽名。但是說實在的弧圆,官方文檔說的其實也不是特別明確赋兵,還是需要摸索和實踐。
參考
https://source.android.google.cn/docs/security/features/apksigning/v3?hl=zh-cn
https://developer.android.google.cn/tools/apksigner?hl=zh-cn#options-sign-general
https://wenchiching.wordpress.com/category/android/
實踐
我準(zhǔn)備了1個小的測試apk搔预,命名為origin.apk霹期。老開發(fā)者證書文件為old.jks,新開發(fā)者證書文件為new.jks拯田,整體放在了本次的工作目錄中历造。后續(xù)命令運行在此目錄。
另外船庇,為了方便執(zhí)行命令吭产,可以配置一下環(huán)境變量,主要把build-tools/xx.x.x和platform-tools兩個目錄配上鸭轮,我們本次會用到的adb和apksigner就在這兩個目錄中臣淤,apksigner要選擇高版本的,不能太舊窃爷,我使用的是build-tools/34.0.0中的apksigner(windows系統(tǒng)下可能是apksigner.bat邑蒋,一樣的)。
思路是這樣的:我們先用兩個證書分別簽名origin.apk按厘,生成old.apk医吊,new.apk。然后再使用輪換簽名的方法逮京,生成一個過渡的old-new.apk遮咖。然后分別驗證覆蓋安裝的情況。
期望效果是:old.apk可以升級到old-new.apk造虏,old-new.apk可以直接升級到new.apk御吞。
注意:使用本文的方法需要拋棄Android9以下的設(shè)備的支持。另外漓藕,命令中一定要指定統(tǒng)一的--rotation-min-sdk-version陶珠,這個版本的作用是,當(dāng)apk被安裝在大于等于這個系統(tǒng)版本的設(shè)備上時享钞,才會啟用簽名輪換揍诽,否則將忽略。最低只能寫28栗竖,再低沒有意義了暑脆,因為不支持。
1. 分別簽名
apksigner sign --ks old.jks --min-sdk-version 28 --out old.apk --in origin.apk
apksigner sign --ks new.jks --min-sdk-version 28 --out new.apk --in origin.apk
2. 生成輪換簽名繼承關(guān)系文件
lineage文件的名字可以隨意命名狐肢,可以理解為這是一個簽名變換的歷史添吗,a換成b,b換成c份名,這些先后關(guān)系需要在文件中聲明碟联。打包apk時會用到。
apksigner rotate \
--out ./lineage-old-to-new \
--old-signer --ks old.jks \
--new-signer --ks new.jks
3. 結(jié)合簽名輪換記錄對apk進行簽名
apksigner sign --ks old.jks --next-signer --ks new.jks --lineage ./lineage-old-to-new --rotation-min-sdk-version 28 --min-sdk-version 28 --out old-new.apk --in origin.apk
4. 分別查看apk內(nèi)簽名情況
apksigner verify --print-certs [xxx.apk]
5. 如果有必要僵腺,也可以查看一下apk簽名版本
apksigner verify -v [xxx.apk]
6. 嘗試覆蓋安裝
adb install old.apk
adb install old-new.apk
adb install new.apk
以上順序進行覆蓋均可以平滑升級鲤孵。然而:
adb install old.apk
adb install new.apk
或者
adb install old-new.apk
adb install old.apk
均會報錯:
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package xxx signatures do not match previously installed version; ignoring!]
Performing Streamed Install
adb: failed to install xxx.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package xxx signatures do not match previously installed version; ignoring!]
可見簽名一旦變更就不能安裝舊證書的apk了,升級是單向的辰如,確保安全性普监。