很多人只知道開(kāi)發(fā)完之后簽名發(fā)布,簽名就生成一個(gè)keystore文件就行,而不太清楚具體的簽名流程,現(xiàn)在我就在這邊簡(jiǎn)單過(guò)一遍流程。
本章節(jié)只講流程,不會(huì)詳細(xì)的去分析簽名的源碼,并且可能某些細(xì)節(jié)說(shuō)得不對(duì),但總體流程肯定就是那么一回事,如果有不對(duì)的地方還希望有大佬能夠指點(diǎn)。
一.概念
開(kāi)始之前我們先來(lái)簡(jiǎn)單了解幾個(gè)重要的概念,有助于理解android的簽名流程。
1.加密
數(shù)據(jù)加密的基本過(guò)程就是對(duì)原來(lái)為明文的文件或數(shù)據(jù)按某種算法進(jìn)行處理,使其成為不可讀的一段代碼,通常稱為"密文",使其只能在輸入相應(yīng)的密鑰之后才能顯示出本來(lái)內(nèi)容,通過(guò)這樣的途徑來(lái)達(dá)到保護(hù)數(shù)據(jù)不被非法人竊取、閱讀的目的。
加密一般分為對(duì)稱加密和非對(duì)稱加密。
一般非對(duì)稱加密更為安全,而一般非對(duì)稱加密的操作是用公鑰進(jìn)行加密,接收端用私鑰進(jìn)行解密。
2.消息摘要
又稱數(shù)字摘要或數(shù)字指紋。簡(jiǎn)單來(lái)說(shuō)就是任意長(zhǎng)度數(shù)據(jù)經(jīng)過(guò)單向的HASH函數(shù),生成一個(gè)固定長(zhǎng)度的HASH值。也就是經(jīng)過(guò)算法處理后的一個(gè)固定長(zhǎng)度的數(shù)據(jù)。
3.數(shù)字簽名
數(shù)字簽名的作用就是保證信息傳輸?shù)耐暾浴l(fā)送者的身份認(rèn)證、防止交易中的抵賴發(fā)生。數(shù)字簽名技術(shù)是將摘要信息用發(fā)送者的私鑰加密,與原文一起傳送給接收者。接收者只有用發(fā)送者的公鑰才能解密被加密的摘要信息然后用HASH函數(shù)對(duì)收到的原文產(chǎn)生一個(gè)摘要信息,與解密的摘要信息對(duì)比。如果相同,則說(shuō)明收到的信息是完整的,在傳輸過(guò)程中沒(méi)有被修改,否則說(shuō)明信息被修改過(guò),因此數(shù)字簽名能夠驗(yàn)證信息的完整性。
和加密相比正好返過(guò)來(lái),是用私鑰加密,用公鑰解密。
4.數(shù)字證書(shū)
數(shù)字證書(shū)就是互聯(lián)網(wǎng)通訊中標(biāo)志通訊各方身份信息的一串?dāng)?shù)字。簡(jiǎn)單來(lái)說(shuō)就是能證明通信方的身份,能確定和我通信的是你,而不是某個(gè)假冒你的人。
假如你這邊把應(yīng)用用私鑰簽名,把簽名后的文件和公鑰都發(fā)給接收端。但是如果中間有人攔截,把文件換了,重新用自己的私鑰簽名,再換對(duì)應(yīng)的公鑰發(fā)給接收端。接收端依舊能正常校驗(yàn)成功,難道這就說(shuō)明這個(gè)文件是正確的嗎?所以才需要數(shù)字證書(shū)來(lái)證明這個(gè)公鑰來(lái)自于真正的發(fā)送端。
二. 簽名過(guò)程
單單這樣講這些概念,還是有點(diǎn)難以理解,我們就用簽名的各個(gè)步驟來(lái)加深上面的每個(gè)概念。
1. android簽名的工具
android有兩種簽名工具jarsigner和signapk。jarsigner在JDK里面,apksigner在build-tools里面,具體的路徑可以自行百度,因?yàn)槲也桓冶WC所有版本的路徑是固定不變的。
jarsigner會(huì)生成keystore,也就是我們用AS的簽名能生成keystore。signapk能生成pk8和pem。這兩方也是可以轉(zhuǎn)換的。
2. 簽名和校驗(yàn)大概流程
按抽象來(lái)說(shuō)(這是按我的理解,也行細(xì)節(jié)上有些差別),簽名和校驗(yàn)的大概過(guò)程是,發(fā)送者把文件用算法生成摘要,再用私鑰對(duì)摘要進(jìn)行加密,把證書(shū)、文件、加密串、公鑰發(fā)給接收端。接收端獲取到之后,根據(jù)證書(shū)認(rèn)真發(fā)送者身份,用公鑰對(duì)加密串進(jìn)行解密,再對(duì)文件也用算法生成摘要,對(duì)比解密之后的信息和摘要的信息是否相同。網(wǎng)上有張圖挺形象的描述這個(gè)過(guò)程。

3. android簽名生成的三個(gè)文件
對(duì)代碼簽名之后會(huì)生成三個(gè)文件:MANIFEST.MF、CERT.SF和CERT.RSA。
如果你解壓apk或者反編譯apk的話會(huì)看到一個(gè)META-INF文件夾,打開(kāi)里面就包含這3個(gè)文件

這三個(gè)文件是在簽名過(guò)程中生成的。
這里就抽象講講生成過(guò)程,不說(shuō)源碼,網(wǎng)上也很多講這3個(gè)文件的生成代碼。
(1)MANIFEST.MF
MANIFEST.MF的內(nèi)容是所有文件進(jìn)行SHA-1(這是一個(gè)Hash算法)之后再base64編碼之后的值。去遍歷所有文件,一個(gè)一個(gè)文件夾遍歷,要是有文件,就SHA-1再base64。無(wú)論你每個(gè)文件長(zhǎng)度怎樣,每個(gè)文件都會(huì)生成一個(gè)固定長(zhǎng)度的值,再把這些值一行一行記錄下來(lái)(當(dāng)然除了所有文件還有其他的屬性,這個(gè)可以自行百度)。

可以看出這個(gè)過(guò)程就是一個(gè)獲取摘要的過(guò)程,把不固定長(zhǎng)度的文件生成固定長(zhǎng)度的字符串。
(2)CERT.SF
其實(shí)就是將MANIFEST.MF文件按一定規(guī)則再進(jìn)行SHA-1之后再base64。

SHA1-Digest-Manifest屬性是對(duì)整個(gè)MANIFEST.MF文件做SHA1再base64生成的串。
之后的每個(gè)SHA1-Digest是對(duì)MANIFEST.MF的各個(gè)條目做SHA1再用base64。
所以這個(gè)過(guò)程還是一個(gè)獲取摘要的過(guò)程。
(3)CERT.RSA

可以看出CERT.RSA不同于上邊兩個(gè)文件,是一個(gè)加密串。
CERT.RSA包含了很多東西。CERT.SF文件用私鑰加密,然后把數(shù)字證書(shū),公鑰等一起組合在一起生成CERT.RSA。
可以看出這是一個(gè)用私鑰加密的過(guò)程。
4. 簽名驗(yàn)證的過(guò)程
安裝的時(shí)候,會(huì)驗(yàn)證這三個(gè)文件,判斷是否完整,這個(gè)其實(shí)很好理解。
我們一般會(huì)經(jīng)歷過(guò)這樣的一種情況,我們手機(jī)已經(jīng)安裝過(guò)一個(gè)文件,如果用不同的簽名就會(huì)安裝出錯(cuò),如果使用相同的簽名就能覆蓋安裝。
安裝時(shí)先會(huì)去查找是否已安裝過(guò)相同的包名的應(yīng)用,然后拿到證書(shū)指紋和要安裝應(yīng)用的證書(shū)指紋進(jìn)行判斷,相同的話說(shuō)明是同一個(gè)應(yīng)用。
至于指紋證書(shū)的原理我也不是很懂,在網(wǎng)上看到有人說(shuō)是jks中X509證書(shū)的摘要信息,也有說(shuō)是證書(shū)發(fā)行者對(duì)證書(shū)的數(shù)字簽名。
而這些信息會(huì)存在CERT.RSA中,所以這個(gè)校驗(yàn)過(guò)程是在校驗(yàn)CERT.RSA的時(shí)候操作的。
大概的一個(gè)簽名和驗(yàn)證的過(guò)程基本就是這樣。