背景
最近因?yàn)榭拥膐ppo r9s導(dǎo)致自己做的android性能搜集apk因?yàn)闄?quán)限原因搜集不到系統(tǒng)進(jìn)程mediaserver的消息,大佬一怒之下讓我去搞個(gè)系統(tǒng)簽名。
但是之前在某手機(jī)廠商做這個(gè)東西的時(shí)候,根本不需要什么技術(shù)含量,只需要在AndroidManifest.xml文件里面加上shardUid,如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx.xxx"
android:sharedUserId="android.uid.system">
然后掛到j(luò)enkins去構(gòu)建一下即可。。。然而,去來(lái)混遲早要還的。。。之前不了解系統(tǒng)簽名是怎么搞的,只好自己慢慢去摸索了。
思考
按照之前的經(jīng)驗(yàn),就是先把sharedUserId加上去,先試一下怎么樣。。不出所料,果然在oppo上面安裝失敗了。
所以還是要去找一下怎么搞定這個(gè)系統(tǒng)簽名
然后上網(wǎng)查看一下,參考了這篇文章
http://m.itdecent.cn/p/47265c8899b5
提及了三種簽名方式:
1.修改android源碼
2.手動(dòng)用signapk去編譯
3.用android studio以及import tool去編譯
分析了一下,第一種方法可行性太低。。。
第二種的話,需要了解一下android apk 的二次打包是個(gè)什么東西,要不然可能會(huì)有坑
第三種應(yīng)該算是比較靠譜的解決方式了,下面就開始自己試一下
步驟
1.獲得系統(tǒng)簽名文件
如果需要系統(tǒng)編譯的話,需要到指定的android build 的build/target/product/security 文件夾下面去找這兩個(gè)文件
- platform.x509.pem
- platform.pk8
為什么需要這兩個(gè)文件?
了解這個(gè)首先需要了解x509到底是什么,搜google x509 certificate可以到wikipedia那里找到概念描述https://en.wikipedia.org/wiki/X.509
其實(shí)x509就是證書的一種標(biāo)準(zhǔn)格式,主要用于SSL/TSL的通信,也會(huì)用到離線應(yīng)用的驗(yàn)證,里面包含了公鑰信息和頒發(fā)者的信息,頒發(fā)者可以是個(gè)人也可以是某個(gè)機(jī)構(gòu)。
而PEM是一種編碼證書的編碼格式,可以包含一系列的key和x509證書
可想而知pk8對(duì)應(yīng)的應(yīng)該就是私鑰存放的格式,全稱是PKCS 8 - Public-Key Cryptography Standards (PKCS)(https://en.wikipedia.org/wiki/PKCS) published by RSA Laboratories.
那么回答為什么需要這兩個(gè)文件就顯而易見了,這個(gè)是針對(duì)platform應(yīng)用簽名的公私鑰對(duì)
2.生成自己的簽名文件
在Android Studio里面按照步驟生成一份jks文件,具體怎么操作就不細(xì)講了。
什么是jsk文件?
jsk其實(shí)就是java定下來(lái)定一套私鑰、證書格式文件,好像生成需要有而外的密碼,別名什么的信息。應(yīng)該是和pem\pk8文件相互轉(zhuǎn)化的
3.用工具把系統(tǒng)簽名文件導(dǎo)入自己的簽名文件
貌似參考文章有些坑爹,似乎是不用生成自己的簽名文件的,這個(gè)工具只不過是把pem\pk8文件轉(zhuǎn)換成一個(gè)jks文件而已
對(duì)于博文里面說到要把命令放在一個(gè)sh文件里也是很扯淡的,直接執(zhí)行命令就可以了
工具:https://github.com/getfatday/keytool-importkeypair
這里有個(gè)使用參考http://www.cnblogs.com/platte/p/3511814.html
命令格式:
./keytool-importkeypair -k myJks.jks -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias MySign
然后就會(huì)生成你的jks文件了
那么問題來(lái)了,怎么保證我的pem,pk8成功轉(zhuǎn)換成了jks呢?
其實(shí)這個(gè)問題很好解決,我們只要找工具去看一下我們pem,pk8的信息和jks的信息是不是對(duì)的上就可以了。
那么問題又定向到了什么工具可以查看這些信息呢?
在你安裝jdk的時(shí)候,sun公司已經(jīng)提供了keytool這一個(gè)工具了,這個(gè)工具不僅可以產(chǎn)生秘鑰對(duì),也可以查看我們的key值是什么。所以只要你的JAVA_HOME和PATH配置好了,就可以直接在命令行里使用了
查看jks : keytool -list -v -keystore [~/keystore文件夾/keystore.jks] -storepass 123456
注意上面-keystore后面必須要跟jks文件的絕對(duì)路徑
查看pem:keytool -printcert -file [pem絕對(duì)路徑]
然后目前我看到在keystore里面的文件的一大段和pem都是一樣的,雖然不知道那一堆那些是公鑰。還是說公鑰就是整個(gè)文件?后面再搞清楚吧,現(xiàn)在只要直到這個(gè)工具是真的ok就行了
4.用新的簽名文件構(gòu)建apk
在android studio 里面配置,網(wǎng)上的教程一搜一大堆啦。其實(shí)就是在app里面的build.gradle配置下面的這段
signingConfigs {
release {
storeFile file("/xxx/myJks.jks")
storePassword '123456'
keyAlias 'MySign'
keyPassword '123456'
}
debug {
storeFile file("/xxx/myJks.jks")
storePassword '123456'
keyAlias 'MySign'
keyPassword '123456'
}
}
如果想要直接生成release的還要再改一下build之類的參數(shù)
5.安裝apk
然后就是安裝apk了,這里單獨(dú)把安裝apk拿出來(lái)說,是想著說安裝的時(shí)候是涉及到PackageManager這個(gè)東西的。
因?yàn)榱粢獾疆?dāng)點(diǎn)擊android studio里面的run按鈕的時(shí)候,run那個(gè)窗口會(huì)出現(xiàn)一系列的adb 命令,其中有一條就是pm install xxx.apk。說明其實(shí)我們?cè)赼ndroid studio里安裝apk到手機(jī)本質(zhì)上也是調(diào)用命令的。
那么思維拓展一下,在手機(jī)里點(diǎn)擊安裝apk,應(yīng)該也是調(diào)用pm這個(gè)service的。那么簽名的驗(yàn)證過程不出所料也是在PackageManagerService里面做的,所以后續(xù)會(huì)寫多篇博文來(lái)研究一下相應(yīng)的源碼,主要是博客上面轉(zhuǎn)載的太多了,都不知道轉(zhuǎn)載的博主有沒有思考過。
問題
1.安裝失敗究竟是什么原因?
留意到安裝報(bào)錯(cuò)的源碼是在packageManagerService里面校驗(yàn)系統(tǒng)應(yīng)用簽名時(shí)包的錯(cuò),所以猜想可能的原因有:
- 找的秘鑰錯(cuò)了,因?yàn)槲业拿罔€是從aosp上面給刮下來(lái)的,跟oppo的對(duì)不上
- 我簽名的apk有沒有問題
對(duì)于第一點(diǎn)應(yīng)該是最有可能的,因?yàn)閛ppo應(yīng)該會(huì)定制過他們系統(tǒng)應(yīng)用的key的。
第二點(diǎn)的話,對(duì)應(yīng)了pem和jks的內(nèi)容應(yīng)該是沒差的。
總結(jié)
每個(gè)ODM他們的platform簽名對(duì)應(yīng)該是定制過的,所以我們拿aosp里面對(duì)應(yīng)的key去簽名應(yīng)該是不可行的。在系統(tǒng)簽名校驗(yàn)的時(shí)候會(huì)通不過,如果是自己玩玩原生的系統(tǒng)的話應(yīng)該是沒問題的