Android 應用程式簽名:它的工作原理及其重要性
每次您在 Android 手機上安裝應用程式時,都會在背景進行無聲但關鍵的安全檢查。您的手機會驗證APK套件的數位簽名。這種加密握手可以防止惡意駭客用惡意軟體「毒害」您的應用程序,同時確保開發人員可以在不丟失身份的情況下推送更新。
如果您編寫應用程序,則只需正確執行簽名即可;如果您只是喜歡擺弄 Android,那麼它是系統中最容易理解的部分之一。不管怎樣,應用程式簽署的工作原理 都值得你花時間。以下我們將介紹該技術、簽名方案的演變以及如何在線上進行 手動驗證證書。
- 為什麼每個 Android 應用程式都必須簽署以及涉及哪些加密技術 (RSA / EC)。
- v1 (JAR)、v2、v3 和 v4 簽章方案之間的區別,以及您的應用程式現在應該使用哪一個。
- Android 如何根據簽章連續性決定是否允許更新。
- 金鑰輪換如何讓開發人員在不破壞現有安裝的情況下更改其簽署金鑰。
- 如何透過命令列或使用我們的 基於瀏覽器的驗證器 自行驗證任何 APK 的簽章。
什麼是應用程式簽名?
應用程式簽名的核心是開發人員使用 私鑰 為其應用程式檔案產生簽名區塊的過程。然後將對應的 公鑰 嵌入到 META-INF 資料夾內的 APK 中。當您的手機嘗試安裝應用程式時,它會使用公鑰來檢查簽名是否與檔案內容相符。
這提供了兩個主要屬性:
- 不變性: 如果應用程式程式碼的單一位元組被更改(例如,被木馬更改),簽名將不再與檔案匹配,Android 將拒絕安裝它。
- 身份證明: 如果應用程式嘗試更新現有應用程序,則它們的簽章必須相符。這就是為什麼你不能在官方應用程式上安裝被篡改的 Facebook 應用程式。
簽名方案的演變
Google不斷升級簽名機制以提高速度和安全性:
- V1(Jar 簽名): 对 APK (ZIP) 中的各个文件进行签名。这很慢,因为操作系统必须解压缩并检查每个文件。它也容易受到某些 ZIP 操作的影響。
- V2(APK簽章方案): 对 APK 的整个二进制块进行签名。它不需要解壓縮來驗證,而且速度非常快。它是在 Android 7.0 (Nougat) 中引入的。
- V3(密鑰輪換): 透過新增金鑰「沿襲」來擴展 V2。它允許開發人員證明新密鑰是舊密鑰的授權繼承者。在 Android 9.0(Pie)中引入。
- V4(串流簽名): 專為增量安裝而設計,可在透過 USB 或 Wi-Fi 下載應用程式時進行驗證。
為什麼憑證對於旁加載很重要
當您從非官方來源下載 APK 時,證書哈希 是您最好的朋友。憑證指紋(例如 SHA-256 雜湊)唯一標識開發人員的簽署金鑰。每個應用程式在其所有更新中保留相同的簽章金鑰,因此您可以將 APK 的指紋與開發人員發布的值進行比較,以確認其真實性。
如果您懷疑 APK 是假的,您應該透過我們的 線上 APK 驗證器 來運行它。我們的工具將向您展示:
- 簽署者的 通用名(中文)(例如“Android”)。
- 證書的有效期限。
- SHA-1/SHA-256 指紋。
Android 如何在安裝時驗證簽名
「驗證憑證」步驟經常被掩蓋,因此值得了解當您點擊 APK 並且 Android 決定是否安裝它時作業系統實際執行的操作:
- 以 ZIP 格式開啟 APK 並找到簽名區塊。 對於 v2/v3 簽名,它是緊鄰中央目錄之前的結構化區塊;對於舊版 v1 方案,它是 META-INF/*.RSA、*.DSA 或 *.EC 的內容。
- 計算 APK 每隔一個位元組的 SHA-256 摘要。 簽章區塊被排除在自己的摘要之外;其他所有內容都以定義的區塊進行雜湊。
- 根據簽名區塊中記錄的摘要驗證每個區塊的摘要。 如果自開發人員簽署文件以來甚至更改了一個字節,則摘要將不匹配,並且安裝將被拒絕,並顯示一般的“應用程式未安裝”錯誤。
- 驗證簽名區塊本身是使用憑證的私鑰產生的。 憑證的公鑰用於檢查區塊中的加密簽章。成功的檢查意味著簽署該文件的人擁有與該證書配對的私鑰。
- 將憑證指紋與具有相同軟體包名稱的任何現有安裝進行比較。 如果軟體套件已安裝且新 APK 使用不同的憑證進行簽名,則安裝將被拒絕,並顯示 INSTALL_FAILED_UPDATE_INCOMPATIBLE。這是作業系統的主要反假冒防禦:惡意行為者無法用自己的副本替換您的銀行應用程序,除非他們還竊取了銀行的簽名密鑰。
這些都不能證明開發人員是值得信賴的,只是您要安裝的文件與他們簽署的文件在字節上相同,並且沒有其他方篡改過它。對開發人員的信任是一項單獨的決定,您可以透過決定安裝的來源來做出決定。
「簽名不符」的真正意義是什麼
側面加載時最常見的意外是更新時出現“簽名不匹配”錯誤。這是實際發生的情況:
- 您已從 Play 商店安裝了 應用程式X版本1.0。
- 您從非 Play 來源下載 應用程式X版本1.1。
- 作業系統看到相同的套件名稱 (com.example.app,但 APK 使用不同的憑證進行簽署(側來源的簽署金鑰,而不是原始發布者的)。它拒絕安裝)。
在實務中,這種情況有兩種發生方式:
- 第三方 APK 是 真正來自不同的出版商,例如「修改」或「修補」副本。拒絕安裝是正確的行為;安裝它意味著信任陌生人擁有您銀行應用程式已經接觸過的相同資料。
- 第三方 APK 是 重新上傳官方APK,但 Google 的 Play 應用程式簽名系統使用使用者的 上傳金鑰 包裝器對每個使用者的下載進行簽署。對於相同概念應用程式版本,兩個裝置有時會看到略有不同的簽章資料。在這種情況下,根處的證書指紋仍然匹配;您可以透過我們的APK驗證器進行驗證。
如果憑證指紋 確實 與您現有的安裝不同,唯一的方法是在旁加載替換之前先卸載目前副本(遺失其資料),切勿停用簽章驗證。
產生您自己的簽名金鑰(針對開發人員)
如果您正在建立 Android 應用程序,您最終需要簽署自己的建置版本。使用 Java SDK 中的 keytool 的標準一行指令是:
keytool -genkeypair -v \
-keystore my-release.keystore \
-alias my-app -keyalg RSA -keysize 2048 \
-validity 10000
有兩件事要知道:
- 有效性 很重要:10000 天(約 27 年)是傳統值,因為作業系統將使用即將過期或過期的金鑰簽署的更新視為已洩露。產生一次長期金鑰並對其進行保護。
- 一旦發布,您就無法輕易切換金鑰。 v3 簽章方案新增了金鑰 旋轉 作為明確功能:舊證書透過儲存的證明「祝福」新證書,允許作業系統接受新金鑰的更新,同時保持身分連續性。如果没有 v3,丢失原始密钥意味着孤立所有现有安装。
對於旁加載測試版本,未簽署的偵錯金鑰庫就可以了;對於生產,請使用儲存在離線備份中的受密碼保護的長期有效金鑰庫。
常見的簽名陷阱
- 自簽名證書: 大多數 Android 應用程式都是自簽署的。與網站的 SSL 不同,Android 應用程式簽名沒有中央機構。您必須直接信任開發商。
- 調試證書: 為測試而建構的應用程式使用通用「調試」金鑰。這些應用程式永遠不應該向公眾發布,並且會被許多安全過濾器阻止。
- 鑰匙遺失: 如果開發人員遺失了他們的私人金鑰庫,他們可以 絕不 再次更新他們的應用程式。他們必須發布一個具有不同包名稱的“新”應用程式。
為您的目標 SDK 選擇正確的簽章方案
應用程式簽名悄悄支撐著 Android 的安全性。一旦私鑰/公鑰關係點擊,您就可以判斷側載應用程式的優點,並確認您正在安裝的內容自開發人員簽署以來沒有被更改。有關 Android 內部結構的更多信息,請參閱我們的 XAPK 格式指南。