Lược đồ chữ ký APK phiên bản 4

Android 11 hỗ trợ lược đồ ký tương thích truyền trực tuyến bằng APK Lược đồ chữ ký phiên bản 4. Chữ ký v4 dựa trên cây hàm băm Merkle được tính trên tất cả byte của APK. Hàm này tuân thủ chính xác cấu trúc của cây băm fs-verity (ví dụ: không khoảng đệm) dữ liệu ngẫu nhiên và 0 khoảng đệm trong khối cuối cùng). Android 11 lưu trữ chữ ký trong một tệp riêng, <apk name>.apk.idsigChữ ký A v4 yêu cầu chữ ký v2 hoặc v3 bổ sung.

Định dạng tệp

Tất cả các trường số đều ở dạng số cuối nhỏ. Tất cả các trường đều chiếm chính xác số số byte làm sizeof() của chúng, không có khoảng đệm ngầm ẩn hoặc đã căn chỉnh.

Dưới đây là cấu trúc trợ giúp để đơn giản hoá các định nghĩa.

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

Nội dung tệp chính:

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 là các tham số dùng cho cây băm tạo + hàm băm gốc:

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 có cấu trúc sau:

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 được lấy từ khối ký phiên bản 3 của APK hoặc nếu không hiện tại, từ khối v2 (xem apk_describe)

Để tạo và xác minh mã signature, bạn phải chuyển đổi tuần tự dữ liệu sau vào blob nhị phân và truyền vào thuật toán ký / xác minh dưới dạng dữ liệu đã ký:

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_treetoàn bộ cây Merkle của APK, được tính như mô tả trong tài liệu fs-verity.

Nhà sản xuất và người tiêu dùng

Công cụ SDK Android apksigner nay tạo tệp chữ ký v4 nếu bạn chạy phương thức đó với các tham số mặc định. Bạn có thể vô hiệu hoá tính năng ký bằng v4 theo cách tương tự giống như các chương trình ký khác. Công cụ này cũng có thể xác minh xem chữ ký v4 có hợp lệ.

adb dự kiến tệp .apk.idsig sẽ xuất hiện bên cạnh tệp .apk khi chạy lệnh adb install --incremental
Công cụ này cũng sẽ sử dụng tệp .idsig để dùng thử phương thức Cài đặt gia tăng bằng cách mặc định và sẽ quay lại cài đặt thông thường nếu thiếu hoặc không hợp lệ.

Khi một phiên cài đặt được tạo, API cài đặt truyền trực tuyến mới trong PackageInstaller chấp nhận loại bỏ chữ ký v4 làm đối số riêng khi thêm tệp vào phiên. Tại thời điểm này, signing_info được chuyển vào incf dưới dạng một toàn bộ blob. Incfs trích xuất hàm băm gốc từ blob.

Khi phiên cài đặt đang được cam kết, PackageManagerService sẽ một ioctl để truy xuất blob signing_info từ incfs, phân tích cú pháp và xác minh chữ ký.

Thành phần Trình tải dữ liệu gia tăng dự kiến sẽ truyền trực tuyến phần cây Merkle của chữ ký thông qua API gốc của trình tải dữ liệu.
Lệnh shell dịch vụ package install-incremental chấp nhận tệp chữ ký v4 bị xoá được mã hoá dưới dạng base64 làm thông số cho từng tệp tệp được thêm vào. Cây Merkle tương ứng phải được gửi vào stdin.

apk_describe (thông báo apk)

apk_digest là chuỗi đại diện nội dung đầu tiên có sẵn theo thứ tự:

  1. V3, khối 1MB, SHA2-512 (CONTENT_ gốc_CHUNKED_SHA512),
  2. V3, khối 4KB, SHA2-256 (CONTENT_ gốc_VERITY_CHUNKED_SHA256),
  3. V3, khối 1MB, SHA2-256 (CONTENT_ gốc_CHUNKED_SHA256),
  4. V2, SHA2-512
  5. V2, SHA2-256.

Xem phần length-có tiền tố trình tự các chữ ký có tiền tố độ dài trong Lược đồ chữ ký APK v3.

quy trình xác thực tệp APK phiên bản 4
Hình 1: Quy trình xác thực APK v4

Xác thực và kiểm thử

Xác thực cách triển khai bằng cách sử dụng tính năng Kiểm thử đơn vị tính năng và CTS.

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

Kiểm thử định dạng chữ ký

Để kiểm tra định dạng chữ ký, hãy thiết lập môi trường phát triển và chạy các bài kiểm thử thủ công sau:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

Kiểm thử định dạng chữ ký bằng SDK Android (ADB và apksigner)

Để kiểm thử định dạng chữ ký với SDK Android, hãy thiết lập một môi trường phát triển và đảm bảo bạn đã hoàn tất việc triển khai IncFS. Sau đó, cài đặt ROM bản dựng trên một thiết bị thực hoặc trình mô phỏng thực tế mục tiêu. Bạn cần để tạo hoặc lấy APK hiện có rồi tạo khoá ký gỡ lỗi. Cuối cùng, ký và cài đặt APK ở định dạng chữ ký v4 từ thư mục build-tools.

Ký hiệu

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

Cài đặt

$ ./adb install game.apk

Có thể tìm thấy những thử nghiệm này ở đâu?

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