經(jīng)常使用的總結(jié):
debug 簽名:
development/tools/make_key media '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key networkstack '/C=CN/ST=BeiJing/L=ChaoYang/O=/OU=xxx/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key platform '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key shared '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key testkey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=debug/CN=xxx/emailAddress=cm@xxx.com'
user簽名:
development/tools/make_key media '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key networkstack '/C=CN/ST=BeiJing/L=ChaoYang/O=user/OU=Pwe/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key platform '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key shared '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
development/tools/make_key testkey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=user/CN=xxx/emailAddress=cm@xxx.com'
ota:
../development/tools/make_key releasekey '/C=CN/ST=BeiJing/L=ChaoYang/O=xxx/OU=xxx/CN=xxx/emailAddress=cm@xxxx.com'
查看生成的格式文件:
keytool -printcert -file platform.x509.pem
使用signapk.jar 進(jìn)行簽名:android10:
java -Djava.library.path="out/host/linux-x86/lib64" -jar out/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 old.apk new.apk
android 11:
./soong/host/linux-x86/framework/signapk.jar
如何產(chǎn)生jsk (keystore)文件, 只做了debug 模式發(fā)的
./keytool-importkeypair -k test.jks -p android -pk8 platform.pk8 -cert platform.x509.pem -alias test
如何查看test.jks 是否正確:
keytool -list -v -keystore test.jks
Android studio 如何使用:
signingConfigs {
releaseConfig {
keyAlias 'test'
keyPassword 'android '
storeFile file('/home/xxx/tools/keystore/test.jks')
storePassword 'android '
}
}
AndroidManifest.xml的manifest節(jié)點(diǎn)中添加
android:sharedUserId=”android.uid.system”煤蹭,
Android.mk中增加 LOCAL_CERTIFICATE := platform
APK中的META-INF/CERT.RSA
簽名之后如何對(duì)RSA 進(jìn)行查看,簽名的信息,在android root目錄
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
本文主要講解簽名的原因华蜒,簽名怎么保證數(shù)據(jù)的正確,主要知識(shí)點(diǎn)
- 數(shù)據(jù)摘要(數(shù)據(jù)指紋,消息摘要)
- 簽名文件和證書
- 簽名Apk包與沒有簽名的APK 差異在哪里
- 如何對(duì)apk 進(jìn)行簽名
1-數(shù)據(jù)摘要
就是對(duì)一個(gè)數(shù)據(jù)源進(jìn)行一個(gè)算法之后得到一個(gè)摘要,也叫作數(shù)據(jù)指紋呈昔,不同的數(shù)據(jù)源柄粹,數(shù)據(jù)指紋肯定不一樣墙懂,就和人一樣
消息摘要算法(Message Digest Algorithm)是一種能產(chǎn)生特殊輸出格式的算法,其原理是根據(jù)一定的運(yùn)算規(guī)則對(duì)原始數(shù)據(jù)進(jìn)行某種形式的信息提取佛嬉,被提取出的信息就被稱作原始數(shù)據(jù)的消息摘要逻澳。
著名的摘要算法有RSA公司的MD5
算法和SHA-1
算法及其大量的變體。
- 無論輸入的消息有多長(zhǎng)暖呕,計(jì)算出來的消息摘要的長(zhǎng)度總是固定的斜做。
- 原始數(shù)據(jù)不同,消息摘要不相同
- 具有不可逆性
2-簽名文件和證書
消息的發(fā)送者來說湾揽,先要生成一對(duì)公私鑰對(duì)瓤逼,將公鑰給消息的接收者
- 提取原始消息提取消息摘要;
- 私鑰加密消息摘要;
上面就是所原始信息的數(shù)字簽名库物“云欤【數(shù)字簽名=私鑰對(duì)[原始數(shù)據(jù)摘要]
】
消息的接受者來說,收到了:原始的消息內(nèi)容+附加數(shù)字簽名.
接收者收到內(nèi)容:原始的消息內(nèi)容+私鑰對(duì)[原始數(shù)據(jù)摘要]
驗(yàn)證正確需要數(shù)據(jù)摘要算法+公鑰
戚揭,公鑰假設(shè)是正確的诱告。
如何驗(yàn)證:數(shù)據(jù)摘要算法對(duì)內(nèi)容提取摘要 對(duì)比
公鑰解密簽名
圖示驗(yàn)證過程:
3-如何保證公鑰是正確的
數(shù)字證書措伐,一般包含以下一些內(nèi)容:
- 證書的發(fā)布機(jī)構(gòu)(Issuer)
- 證書的有效期(Validity)
- 消息發(fā)送方的公鑰
- 證書所有者(Subject)
- 數(shù)字簽名所使用的算法
- 數(shù)字簽名 --》 數(shù)字證書也使用到了數(shù)字簽名揖曾,只不過簽名的內(nèi)容是證書
公鑰簽發(fā)流程
上面核心內(nèi)容就是申請(qǐng)者
提出申請(qǐng)公鑰些己,公信力機(jī)構(gòu)
使用自己的私鑰對(duì)申請(qǐng)者
的公鑰數(shù)字簽名, 公信力機(jī)構(gòu)的公鑰是大家都知道的傍药,因此成功后,申請(qǐng)者的client 端就可以通過公信力機(jī)構(gòu)
獲取靴姿, 以驗(yàn)證公鑰的正確性沃但。
上面的內(nèi)容是我在理解HTTPS ,一直想不通的地方佛吓,現(xiàn)在終于想通了簽發(fā)機(jī)構(gòu)是如何發(fā)送公鑰的维雇。
其實(shí)app 的數(shù)字簽名與上面的CA 機(jī)構(gòu)的簽名還是有點(diǎn)區(qū)別的吱型。
APP 是如何保證簽名流程的:
apk簽名其實(shí)是對(duì)所有源文件單獨(dú)計(jì)算摘要, 然后用私鑰
加密摘要信息再得到一個(gè)加密串, 我們稱之為
APK的簽名. 你對(duì)源文件的修改都會(huì)導(dǎo)致簽名的變化. 這個(gè)是為了驗(yàn)證apk沒有被篡改.
app的升級(jí)和重新安裝, 檢測(cè)的并不是這個(gè)apk簽名, 而是你的包名+私鑰的摘要信息, 簽名的keystore文件沒有變, 私鑰的摘要信息也就不會(huì)變了.
google APP store, 當(dāng)開發(fā)者第一步開發(fā)的時(shí)候唁影,就需要有自己的簽名据沈,私鑰的摘要信息上傳到goole APP store, 如果升級(jí)的時(shí)候锌介, 私鑰的摘要不一致肯定不能升級(jí)app 的上傳隆敢,這里應(yīng)該做了校驗(yàn)的拂蝎。
4-簽名Apk包與沒有簽名的APK 差異在哪里
源碼位置:com/android/signapk/sign.java
Android簽名apk之后惶室,會(huì)有一個(gè)META-INF文件夾皇钞,這里有三個(gè)文件:
- MANIFEST.MF
- CERT.RSA
- CERT.SF
MANIFEST.MF是:
逐一遍歷里面的所有條目,如果是目錄就跳過馆里,如果是一個(gè)文件,就用SHA1(或者SHA256)消息摘要算法提取出該文件的摘要然后進(jìn)行BASE64編碼后以舒,作為“SHA1-Digest”屬性的值寫入到MANIFEST.MF文件中的一個(gè)塊中慢哈。該塊有一個(gè)“Name”屬性卵贱,其值就是該文件在apk包中的路徑。
CERT.SF:
逐條計(jì)算MANIFEST.MF文件中每一個(gè)塊的SHA1编振,并經(jīng)過BASE64編碼后踪央,記錄在CERT.SF中的同名塊中畅蹂,屬性的名字是“SHA1-Digest
CERT.RSA:
把之前生成的 CERT.SF文件液斜, 用私鑰計(jì)算出簽名, 然后將簽名以及包含公鑰信息的數(shù)字證書一同寫入 CERT.RSA 中保存,還有私鑰的摘要信息
5-如何對(duì)apk 進(jìn)行簽名
5.1生成簽名文件
development/tools/make_key testkey '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
development/tools/make_key platform '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
如何查看生成的platform.X509.pem:
build/target/product/security/platform.x509.pem
keytool -printcert -file platform.x509.pem
或者
openssl x509 -inform PEM -subject_hash_old -in platform.x509.pem -text
單獨(dú)給APP簽名方法:
java -Djava.library.path="out/host/linux-x86/lib64" -jar out/host/linux-x86/framework/signapk.jar build/target/product/security/platform.x509.pem build/target/product/security/platform.pk8 old.apk new.apk
APP簽名之后,如何查看CERT.RSA 信息
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text
6-Android OTA releasekey 替換
6.1生成key
系統(tǒng)默認(rèn)的key如下硼被,首先需要產(chǎn)生以下4種我們項(xiàng)目自己的OTA簽名key文件示损,每一種類型的key都是成對(duì)生成的嚷硫,.509.pem后綴名的是公鑰,.pk8后綴名的是私鑰论巍。
testkey -- a generic key for packages that do not otherwise specify a key.
platform -- a test key for packages that are part of the core platform.
shared -- a test key for things that are shared in the home/contacts process.
media -- a test key for packages that are part of the media/download system.
將XXX替換為自己公司信息烛谊。
生成文件如下:
media.pk8 media.x509.pem platform.pk8 platform.x509.pem
releasekey.pk8 releasekey.x509.pem shared.pk8 shared.x509.pem
將生成的key 文件放到項(xiàng)目相關(guān)的目錄下嘉汰,針對(duì)Amlogic項(xiàng)目放到device/amlogic/p341/sign_keys丹禀。這樣我們公司的key就生成了。
6.2.更改編譯規(guī)則,使編譯過程中使用我們新生成的key對(duì)OTA進(jìn)行簽名
首先在build/core/Makefile里搜索testkey, 查看testkey是怎么用到編譯系統(tǒng)的双泪,看到如下編譯選項(xiàng):
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/testkey)
BUILD_KEYS := test-keys
else
BUILD_KEYS := dev-keys
endif
繼續(xù)查看DEFAULT_SYSTEM_DEV_CERTIFICATE
,可以看到在build/core/config.mk文件里有如下:
# The default key if not set as LOCAL_CERTIFICATE
ifdef PRODUCT_DEFAULT_DEV_CERTIFICATE
DEFAULT_SYSTEM_DEV_CERTIFICATE := $(PRODUCT_DEFAULT_DEV_CERTIFICATE)
else
DEFAULT_SYSTEM_DEV_CERTIFICATE := build/target/product/security/testkey
endif
因此要想使用releasekey,只需要指定PRODUCT_DEFAULT_DEV_CERTIFICATE
的值即可焙矛,因此在device/amlogic/p341/p341.mk
中指定項(xiàng)目特定變量
PRODUCT_DEFAULT_DEV_CERTIFICATE := device/amlogic/p341/sign_keys/releasekey
同時(shí)在根據(jù)規(guī)則村斟,在build/core/Makefile
改動(dòng)如下:
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),device/amlogic/p341/sign_keys/releasekey)
BUILD_KEYS := release-keys
endif
6.3. Androoid.mk 使用platform 簽名
對(duì)于apk的簽名,系統(tǒng)會(huì)根據(jù)apk里指定的key進(jìn)行簽名逾滥。如果系統(tǒng)中的apk的android.mk中沒有設(shè)置LOCAL_CERTIFICATE的值寨昙,就默認(rèn)使用testkey。
ifeq ($(LOCAL_CERTIFICATE),)
LOCAL_CERTIFICATE := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
endif
private_key := $(LOCAL_CERTIFICATE).pk8
certificate := $(LOCAL_CERTIFICATE).x509.pem
而如果設(shè)置成:
LOCAL_CERTIFICATE := platform
就代表使用platform來簽名舔哪,這樣的話這個(gè)apk就擁有了和system相同的簽名
如何產(chǎn)生jks文件尚卫,提供給android studio 開發(fā)使用,進(jìn)行系統(tǒng)簽名
jks文件:
第一種方式
https://github.com/chear/keytool-importkeypair
./keytool-importkeypair -k test.jks -p android -pk8 platform.pk8 -cert platform.x509.pem -alias test
最終會(huì)生成 test.jks
-k test.jks: test表示最終生成的jks的名字尸红,可以自定義
android : 輸入當(dāng)前jks的密碼吱涉,可以自定義。
alias test: test表示別名外里,可以自定義怎爵,建議和上面的jks一致。
第二種方式: 該方式作為記錄盅蝗,實(shí)際與第一種方式是想通的鳖链,可以看keytool-importkeypair 腳本
1、編譯android源碼墩莫。
2芙委、cd build/target/product/security/
3、執(zhí)行
openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
生成platform.pem文件
4狂秦、
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:123456 -name test
生成platform.p12文件灌侣,其中 "test" 為alias名(app添加簽名要用到),"123456" 為密碼裂问。
5侧啼、執(zhí)行
keytool -importkeystore -deststorepass test -destkeystore platform.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass test
生成platform.jks (app打簽名最終用到的文件)牛柒,
-deststorepass "123456" 設(shè)置的是這個(gè)簽名的密碼,
-src* 的其他參數(shù)都是從前面兩個(gè)指令中生成的痊乾。
6皮壁、生成platform.jks
keytool -importkeystore -srckeystore platform.jks -destkeystore platform.jks -deststoretype pkcs12
說明:platform.jks 實(shí)際是含有了公鑰與私鑰, 這個(gè)是不能release給第三方的哪审,只能給自己公司研發(fā)使用
思考:
-
一個(gè)數(shù)據(jù)內(nèi)容使用一個(gè)簽名就可以蛾魄,一個(gè)app 使用一個(gè)簽名就可以,如果重復(fù)簽名會(huì)怎么樣湿滓?
重復(fù)使用signapk 簽名會(huì)覆蓋滴须,上次的簽名失效,【沒有使用studio 多次簽名試過茉稠,看到有別名的可以有多個(gè)】
普通簽名與系統(tǒng)簽名的區(qū)別?
簽名是保證數(shù)據(jù)不被改寫
系統(tǒng)簽名就是要獲取一些系統(tǒng)權(quán)限把夸,修改時(shí)間權(quán)限等等
普通簽名僅僅保證數(shù)據(jù)正確而线,單存的app 開發(fā),上傳到APP store 恋日,不需要獲取修改系統(tǒng)的權(quán)限膀篮。app升級(jí)過程中,如何保證升級(jí)APP 數(shù)據(jù)是正確的岂膳?
數(shù)字簽名 與公鑰聯(lián)合誓竿,配合私鑰的數(shù)據(jù)摘要,android 升級(jí)過程進(jìn)行了對(duì)比谈截,如果在第一次安裝設(shè)備時(shí)候就修改了數(shù)字簽名筷屡,那么再次安裝正確的app 不會(huì)成功。 因此老老實(shí)實(shí)從Apple store 下載簸喂,這樣保證app 正確毙死,沒有打廣告等https協(xié)議中的公鑰,私鑰處理方式喻鳄,ssl 中公鑰如何傳遞給使用者扼倘?
通過CA 公信力結(jié)構(gòu),公鑰分發(fā)給使用者除呵,ssl協(xié)議在協(xié)商過程使用非對(duì)稱加密技術(shù)再菊, 最后協(xié)商出對(duì)稱秘鑰進(jìn)行通信,對(duì)稱秘要沒有在網(wǎng)絡(luò)上傳遞颜曾, 是雙方通過算法計(jì)算出來的纠拔。
7 設(shè)計(jì)原則與測(cè)試結(jié)果
7.1設(shè)計(jì)原則
簽名文件規(guī)格:(device.mk設(shè)計(jì)參考之前的)
1)Userdebug 與user 區(qū)別
userdebug 系統(tǒng)platform.jks 有可能release 給別人,因此user版本設(shè)計(jì)成不一樣的泛豪。
user 系統(tǒng)platform.jks 僅僅relase公司的app 開發(fā)人員
2)user 與ota 绿语,只是ota 多了releaseky,其他文件都一樣
7.2測(cè)試華為手機(jī)user version【開發(fā)者模式】:
debug app 可以正常安裝秃症, 在AndroidManifest.xml 添加了
android:sharedUserId="android.uid.system"
release apk(沒有簽名), 不能安裝吕粹,【 在AndroidManifest.xml 添加了
android:sharedUserId="android.uid.system"
release apk(使用platform 簽名[android10 google原生platformq簽名]), 這種方式可以正常安裝
release apk(使用platform 簽名[自己制作android10platformq簽名]), 這種方式可以正常安裝
上面兩種都可以安裝种柑,在運(yùn)行的時(shí)候?qū)ο到y(tǒng)權(quán)限的多種有所不同。release apk(使用platform 簽名[自己制作android10platformq簽名]), 這種方式可以正常安裝匹耕,安裝之后再次對(duì)APK 簽名(使用原生簽名文件)聚请, 發(fā)現(xiàn)CERT.RSA 簽名文件失效, 不能再次安裝稳其,提示簽名不匹配
Performing Streamed Install
adb: failed to install C:\Users\Desktop\old.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.example.demo signatures do not match previously installed version; ignoring!]
REF:
http://www.reibang.com/p/76e5f5e64b85
https://developer.android.google.cn/studio/publish/app-signing
ota relase key 參考
下載文件地址:
git clone https://github.com/getfatday/keytool-importkeypair.git