APK 簽署配置 v4

Android 11 支援使用 APK 的串流相容簽署配置 Signature Scheme v4。v4 簽名以 Merkle 雜湊樹為基礎 計算依據為 APK 的所有位元組完全符合 fs-verity 雜湊樹狀結構的結構 (例如,零填充) 為最後一個區塊 加入鹽和零填充值Android 11 儲存簽名 <apk name>.apk.idsigA v4 簽章 需要補充 v2v3 簽章。

檔案格式

所有數字欄位都使用半形句號。所有欄位都等於數字 做為 sizeof(),沒有隱含邊框間距或 已新增對齊。

以下為簡化定義的輔助結構體。

template <class SizeT>
struct sized_bytes {
        SizeT size;
        byte bytes[size];
};

主要檔案內容:

struct V4Signature {
        int32 version; // only version 2 is supported as of now
        sized_bytes<int32> hashing_info;
        sized_bytes<int32> signing_info;
        sized_bytes<int32> merkle_tree;  // optional
};

hashing_info 是用於雜湊樹狀結構的參數 產生 + 根雜湊:

struct hashing_info.bytes {
    int32 hash_algorithm;    // only 1 == SHA256 supported
    int8 log2_blocksize;     // only 12 (block size 4096) supported now
    sized_bytes<int32> salt; // used exactly as in fs-verity, 32 bytes max
    sized_bytes<int32> raw_root_hash; // salted digest of the first Merkle tree page
};

signing_info 是以下結構:

struct signing_info.bytes {
    sized_bytes<int32> apk_digest;  // used to match with the corresponding APK
    sized_bytes<int32> x509_certificate; // ASN.1 DER form
    sized_bytes<int32> additional_data; // a free-form binary data blob
    sized_bytes<int32> public_key; // ASN.1 DER, must match the x509_certificate
    int32 signature_algorithm_id; // see the APK v2 doc for the list
    sized_bytes<int32> signature;
};
  • apk_digest」是取自 APK 的 v3 簽署區塊;如果不是,則系統會捨棄此區塊 來自於第 2 版區塊 (請參閱 apk_digest)

如要建立並驗證 signature 代碼,必須進行序列化 並將下列資料傳入二進位 blob,並將資料傳送至 簽署 / 驗證演算法做為 已簽署資料

struct V4DataForSigning {
        int32 size;
        int64 file_size; // the size of the file that's been hashed.
        hashing_info.hash_algorithm;
        hashing_info.log2_blocksize;
        hashing_info.salt;
        hashing_info.raw_root_hash;
        signing_info.apk_digest;
        signing_info.x509_certificate;
        signing_info.additional_data;
};
  1. merkle_tree 是 APK 的整個 Merkle 樹狀結構,如 fs-verity 說明文件所述。
,瞭解如何調查及移除這項存取權。

生產者與消費者

apksigner Android SDK 工具現在會產生 v4 簽名檔案 使用預設參數執行時v4 簽署功能同樣可以停用 和其他簽署配置一樣還能確認第 4 版簽名 有效。

adb 預期 .apk.idsig 檔案出現在 .apk 旁邊 執行 adb install --incremental 指令
並利用 .idsig 檔案嘗試 否則會改回使用一般安裝程序 無效。

建立安裝工作階段時,系統會採用新的串流安裝 API。 PackageInstaller 接受條紋 v4 簽章做為個別引數, 目前,signing_info 會做為 整個 blob。Incfs 會從 blob 擷取根雜湊。

修訂安裝工作階段時,PackageManagerService 會 用於從 incfs 擷取 sign_info blob 的 ioctl,加以剖析並驗證 簽章。

增量資料載入器元件應串流 Merkle 樹狀結構部分 已經過資料載入器原生 API 簽署。
package服務殼層指令 install-incremental 接受以 base64 編碼做為參數的簡化 v4 簽名檔案 已新增檔案對應的 Merkle 樹必須傳送到指令的 stdin

apk_摘要

apk_digest 會依序成為第一個可用的內容摘要:

  1. V3、1MB 區塊、SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)、
  2. V3、4 KB 區塊、SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)、
  3. V3、1MB 區塊、SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)、
  4. V2、SHA2-512、
  5. V2、SHA2-256。

請參閱前置字串長度 在 APK 簽名配置 v3 中,且加上前置字串的簽章序列

apk 驗證程序 v4
圖 1:APK 驗證程序 v4

驗證與測試

使用功能單元測試和 CTS 驗證實作成果。

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

測試簽名格式

如要測試簽名格式,請進行設定 開發環境,並執行下列手動測試:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

使用 Android SDK (ADB 和 apksigner) 測試簽名格式

如要透過 Android SDK 測試簽名格式,請設定開發環境 請確認您已完成 IncFS。 然後在目標實體裝置或模擬器上刷新版本。您需要具備 產生或取得現有的 APK,然後建立偵錯簽署金鑰。 最後,簽署並安裝 v4 簽署格式的 APK 從 build-tools 資料夾中載入

簽名

$ ./apksigner sign --ks debug.keystore game.apk

安裝

$ ./adb install game.apk

哪裡可以找到這些測試?

/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java