Android 11 支援使用 APK 的串流相容簽署配置
Signature Scheme v4。v4 簽名以 Merkle 雜湊樹為基礎
計算依據為 APK 的所有位元組完全符合 fs-verity 雜湊樹狀結構的結構 (例如,零填充)
為最後一個區塊
加入鹽和零填充值Android 11 儲存簽名
<apk name>.apk.idsig
A v4 簽章
需要補充 v2 或 v3 簽章。
檔案格式
所有數字欄位都使用半形句號。所有欄位都等於數字
做為 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; };
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
會依序成為第一個可用的內容摘要:
- V3、1MB 區塊、SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)、
- V3、4 KB 區塊、SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)、
- V3、1MB 區塊、SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)、
- V2、SHA2-512、
- V2、SHA2-256。
請參閱前置字串長度 在 APK 簽名配置 v3 中,且加上前置字串的簽章序列。
驗證與測試
使用功能單元測試和 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