APK signature scheme v4

Android 11 mendukung skema penandatanganan yang kompatibel dengan streaming dengan skema tanda tangan APK v4. Tanda tangan v4 didasarkan pada hierarki hash Merkle yang dihitung di semua byte APK. Struktur ini mengikuti struktur hierarki hash fs-verity dengan tepat (misalnya, padding dengan nol pada salt dan padding dengan nol pada blok terakhir). Android 11 menyimpan tanda tangan dalam file terpisah, <apk name>.apk.idsigTanda tangan v4 memerlukan tanda tangan v2 atau v3 pelengkap.

Format file

Semua kolom numerik dalam little endian. Semua kolom menempati jumlah byte yang sama persis dengan sizeof()-nya, tanpa padding atau perataan implisit yang ditambahkan.

Berikut adalah struct bantuan untuk menyederhanakan definisi.

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

Konten file utama:

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 adalah parameter yang digunakan untuk pembuatan hierarki hash + hash root:

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 adalah struct berikut:

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 diambil dari blok penandatanganan v3 APK, atau, jika tidak ada, dari blok v2 (lihat apk_digest)

Untuk membuat dan memverifikasi kode signature, Anda harus melakukan serialisasi data berikut ke dalam blob biner dan meneruskannya ke algoritma penandatanganan / verifikasi sebagai data yang ditandatangani:

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 adalah seluruh hierarki Merkle dari APK, yang dihitung seperti yang dijelaskan dalam dokumentasi fs-verity.

Produsen dan konsumen

Alat Android SDK apksigner kini menghasilkan file tanda tangan v4 jika Anda menjalankannya dengan parameter default. Penandatanganan v4 dapat dinonaktifkan dengan cara yang sama seperti skema penandatanganan lainnya. Fitur ini juga dapat memverifikasi apakah tanda tangan v4 valid.

adb mengharapkan file .apk.idsig ada di samping .apk saat menjalankan perintah adb install --incremental
File ini juga akan menggunakan file .idsig untuk mencoba penginstalan Inkremental secara default, dan akan kembali ke penginstalan reguler jika tidak ada atau tidak valid.

Saat sesi penginstalan dibuat, API penginstalan streaming baru di PackageInstaller menerima tanda tangan v4 yang dihapus sebagai argumen terpisah saat menambahkan file ke sesi. Pada tahap ini, signing_info diteruskan ke incfs sebagai seluruh blob. Incfs mengekstrak hash root dari blob.

Saat sesi penginstalan di-commit, PackageManagerService melakukan ioctl untuk mengambil blob signing_info dari incfs, mengurainya, dan memverifikasi tanda tangan.

Komponen Incremental Data Loader diharapkan akan melakukan streaming bagian hierarki Merkle dari tanda tangan melalui API native loader data.Perintah shell layanan
package install-incremental menerima file tanda tangan v4 yang dihapus dan dienkode sebagai base64 sebagai parameter untuk setiap file yang ditambahkan. Hierarki Merkle yang sesuai harus dikirim ke stdin perintah.

apk_digest

apk_digest adalah ringkasan konten pertama yang tersedia dalam urutan:

  1. V3, blok 1 MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
  2. V3, blok 4 KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
  3. V3, blok 1 MB, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
  4. V2, SHA2-512,
  5. V2, SHA2-256.

Lihat urutan tanda tangan dengan awalan panjang di APK signature scheme v3.

apk validation process v4
Gambar 1: Proses validasi APK v4

Validasi dan pengujian

Validasi implementasi menggunakan Pengujian Unit Fitur dan CTS.

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

Menguji format tanda tangan

Untuk menguji format tanda tangan, siapkan lingkungan pengembangan dan jalankan pengujian manual berikut:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

Menguji format tanda tangan dengan Android SDK (ADB dan apksigner)

Untuk menguji format tanda tangan dengan Android SDK, siapkan lingkungan pengembangan dan pastikan Anda telah menyelesaikan implementasi IncFS. Kemudian, flash build di perangkat fisik atau emulator target. Anda perlu membuat atau mendapatkan APK yang ada, lalu membuat kunci penandatanganan debug. Terakhir, tanda tangani dan instal apk dengan format tanda tangan v4 dari folder build-tools.

Tanda tangan

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

Download

$ ./adb install game.apk

Di mana pengujian ini dapat ditemukan?

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