Android簽名機制
很多人只知道開發完之後簽名釋出,簽名就生成一個keystore檔案就行,而不太清楚具體的簽名流程,現在我就在這邊簡單過一遍流程。
本章節只講流程,不會詳細的去分析簽名的原始碼,並且可能某些細節說得不對,但總體流程肯定就是那麼一回事,如果有不對的地方還希望有大佬能夠指點。
一.概念
開始之前我們先來簡單瞭解幾個重要的概念,有助於理解android的簽名流程。
1.加密
資料加密的基本過程就是對原來為明文的檔案或資料按某種演算法進行處理,使其成為不可讀的一段程式碼,通常稱為"密文",使其只能在輸入相應的金鑰之後才能顯示出本來內容,通過這樣的途徑來達到保護資料不被非法人竊取、閱讀的目的。
加密一般分為對稱加密和非對稱加密。
一般非對稱加密更為安全,而一般非對稱加密的操作是用公鑰進行加密,接收端用私鑰進行解密。
2.訊息摘要
又稱數字摘要或數字指紋。簡單來說就是任意長度資料經過單向的HASH函式,生成一個固定長度的HASH值。也就是經過演算法處理後的一個固定長度的資料。
3.數字簽名
數字簽名的作用就是保證資訊傳輸的完整性、傳送者的身份認證、防止交易中的抵賴發生。數字簽名技術是將摘要資訊用傳送者的私鑰加密,與原文一起傳送給接收者。接收者只有用傳送者的公鑰才能解密被加密的摘要資訊然後用HASH函式對收到的原文產生一個摘要資訊,與解密的摘要資訊對比。如果相同,則說明收到的資訊是完整的,在傳輸過程中沒有被修改,否則說明資訊被修改過,因此數字簽名能夠驗證資訊的完整性。
和加密相比正好返過來,是用私鑰加密,用公鑰解密。
4.數字證書
數字證書就是網際網路通訊中標誌通訊各方身份資訊的一串數字。簡單來說就是能證明通訊方的身份,能確定和我通訊的是你,而不是某個假冒你的人。
假如你這邊把應用用私鑰簽名,把簽名後的檔案和公鑰都發給接收端。但是如果中間有人攔截,把檔案換了,重新用自己的私鑰簽名,再換對應的公鑰發給接收端。接收端依舊能正常校驗成功,難道這就說明這個檔案是正確的嗎?所以才需要數字證書來證明這個公鑰來自於真正的傳送端。
二. 簽名過程
單單這樣講這些概念,還是有點難以理解,我們就用簽名的各個步驟來加深上面的每個概念。
1. android簽名的工具
android有兩種簽名工具jarsigner和signapk。jarsigner在JDK裡面,apksigner在build-tools裡面,具體的路徑可以自行百度,因為我不敢保證所有版本的路徑是固定不變的。
jarsigner會生成keystore,也就是我們用AS的簽名能生成keystore。signapk能生成pk8和pem。這兩方也是可以轉換的。
2. 簽名和校驗大概流程
按抽象來說(這是按我的理解,也行細節上有些差別),簽名和校驗的大概過程是,傳送者把檔案用演算法生成摘要,再用私鑰對摘要進行加密,把證書、檔案、加密串、公鑰發給接收端。接收端獲取到之後,根據證書認真傳送者身份,用公鑰對加密串進行解密,再對檔案也用演算法生成摘要,對比解密之後的資訊和摘要的資訊是否相同。網上有張圖挺形象的描述這個過程。

3. android簽名生成的三個檔案
對程式碼簽名之後會生成三個檔案:MANIFEST.MF、CERT.SF和CERT.RSA。
如果你解壓apk或者反編譯apk的話會看到一個META-INF資料夾,開啟裡面就包含這3個檔案

這三個檔案是在簽名過程中生成的。
這裡就抽象講講生成過程,不說原始碼,網上也很多講這3個檔案的生成程式碼。
(1)MANIFEST.MF
MANIFEST.MF的內容是所有檔案進行SHA-1(這是一個Hash演算法)之後再base64編碼之後的值。去遍歷所有檔案,一個一個資料夾遍歷,要是有檔案,就SHA-1再base64。無論你每個檔案長度怎樣,每個檔案都會生成一個固定長度的值,再把這些值一行一行記錄下來(當然除了所有檔案還有其他的屬性,這個可以自行百度)。

可以看出這個過程就是一個獲取摘要的過程,把不固定長度的檔案生成固定長度的字串。
(2)CERT.SF
其實就是將MANIFEST.MF檔案按一定規則再進行SHA-1之後再base64。

SHA1-Digest-Manifest屬性是對整個MANIFEST.MF檔案做SHA1再base64生成的串。
之後的每個SHA1-Digest是對MANIFEST.MF的各個條目做SHA1再用base64。
所以這個過程還是一個獲取摘要的過程。
(3)CERT.RSA

可以看出CERT.RSA不同於上邊兩個檔案,是一個加密串。
CERT.RSA包含了很多東西。CERT.SF檔案用私鑰加密,然後把數字證書,公鑰等一起組合在一起生成CERT.RSA。
可以看出這是一個用私鑰加密的過程。
4. 簽名驗證的過程
安裝的時候,會驗證這三個檔案,判斷是否完整,這個其實很好理解。
我們一般會經歷過這樣的一種情況,我們手機已經安裝過一個檔案,如果用不同的簽名就會安裝出錯,如果使用相同的簽名就能覆蓋安裝。
安裝時先會去查詢是否已安裝過相同的包名的應用,然後拿到證書指紋和要安裝應用的證書指紋進行判斷,相同的話說明是同一個應用。
至於指紋證書的原理我也不是很懂,在網上看到有人說是jks中X509證書的摘要資訊,也有說是證書發行者對證書的數字簽名。
而這些資訊會存在CERT.RSA中,所以這個校驗過程是在校驗CERT.RSA的時候操作的。