2011年9月28日 星期三

[AndroidSign] apk sign

* Restriction
  • Android 系統禁止更新安裝簽名不一致的 APK。
  • You cannot release your application to the public when signed with the debug certificate.


* Generate apk sign
  • 要簽名一個沒有簽名過的APK,可以使用一個叫作 Auto-sign 的工具。
    • Auto-sign工具實際執行的是一個叫做Sign.bat的批處理命令。
    • 用文本編輯器開啟這個批處理文件。
  • Obtain a suitable private key


* signapk.jar
  • 是 Android 源碼包中的一個簽名工具。路徑為/build/tools/signapk/SignApk.java
  • 對比一個沒有簽名的 APK 和一個簽名好的 APK,會發現,簽名好的 APK 包中多了一個叫做 META-INF 的文件夾。裡面有三個文件:
    • MANIFEST.MF
    • CERT.SF
    • CERT.RSA。
  • signapk.jar 就是生成了這幾個文件(其他文件沒有任何改變。因此我們可以很容易去掉原有簽名訊息)。


* signapk.jar process:

1、生成 MANIFEST.MF 文件
  • 程式遍歷 apk 包中的所有文件(entry),對非文件夾非簽名文件的文件,逐個生成SHA1 的數字簽名訊息,再用 Base64 進行編碼。
  • 之後將生成的簽名寫入 MANIFEST.MF 文件。
  • SHA1 數字簽名
    • 是一種安全 hash 算法,類似於 MD5 算法。它把任意長度的輸入,通過散列算法變成固定長度的輸出(這裡我們稱作「摘要訊息」)。
    • 你不能僅通過這 個摘要訊息復原原來的訊息。另外,它保證不同訊息的摘要訊息彼此不同。
    • 因此,如果你改變了 apk 包中的文件,那麼在 apk 安裝校驗時,改變後的文件摘要信息與 MANIFEST.MF 的檢驗訊息不同,於是程式就不能成功安裝。

2、生成 CERT.SF 文件
  • 對前一步生成的 Manifest,使用 SHA1-RSA 算法,用私鑰進行簽名
  • RSA 是一種非對稱加密算法。
    • 用私鑰通過RSA算法對摘要訊息進行加密。在安裝時只能使用公鑰才能解密它。
    • 解密之後,將它與未加密的摘要訊息進行對比,如果相符,則表明內容沒有被異常修改

3、生成 CERT.RSA 文件
  • CERT.RSA文件中保存了公鑰、所採用的加密算法等訊息。


* Overview
1、 Android 簽名機制其實是對 APK 包完整性和發佈機構唯一性的一種校驗機制。
2、 Android 簽名機制不能阻止 APK 包被修改,但修改後的再簽名無法與原先的簽名保持一致。(擁有私鑰的情況除外)。
3、 APK 包加密的公鑰就打包在 APK 包內,且不同的私鑰對應不同的公鑰。換句話言之,不同的私鑰簽名的APK公鑰也必不相同。所以我們可以根據公鑰的對比,來判斷私鑰是否一致。


* APK Parser
  • 源碼中有一個隱藏的類用於APK 包的解析。這個類叫 PackageParser
  • 路徑為 frameworks\base\core\java\android\content\pm\PackageParser.java
  • 當我們需要獲取APK包的相關訊息時,可以直接使用這個 class。

我們就可以通過 packageInfo.signatures 來訪問到APK的簽名訊息。

它們的關係如下面代碼所示:

也就是說 signature = new Signature(certificate.getEncoded());

certificate 證書中包含了公鑰和證書的其他基本訊息。

公鑰不同,證書肯定互不相同。

我們可以通過 certificate 的 getPublicKey 方法獲取公鑰訊息。

所以比對簽名證書本質上就是比對公鑰訊息



Related
[Android] Debug Key


* Reference
- Android APK簽名對比及說明 - Android 軟體設計 - Android 台灣中文網 - Android(安卓,安致)討論區 - APK.TW **
- Signing Your Applications

沒有留言:

張貼留言