Android 11 hỗ trợ một lược đồ ký tương thích với tính năng phát trực tuyến bằng lược đồ chữ ký APK v4. Chữ ký v4 dựa trên cây băm Merkle được tính toán trên tất cả các byte của APK. Lược đồ này tuân theo cấu trúc chính xác của cây băm fs-verity (ví dụ: đệm muối bằng số 0 và đệm khối cuối cùng bằng số 0). Android 11 lưu trữ chữ ký trong một tệp riêng biệt, <apk name>.apk.idsig. Chữ ký 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 little endian. Tất cả các trường đều chiếm đúng số byte như sizeof(), không có khoảng đệm hoặc căn chỉnh ngầm định nào được thêm vào.
Cấu trúc trợ giúp sau đây 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à tham số dùng để tạo cây băm cùng với 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 là 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. Nếu không có khối này, thì khối này sẽ được lấy từ khối v2 (xem apk_digest).
Để tạo và xác minh, mã signature phải chuyển đổi tuần tự dữ liệu sau đây thành blob nhị phân và truyền dữ liệu đó vào thuật toán ký và 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;
};merkle_tree là toà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ụ apksigner Android SDK sẽ tạo tệp chữ ký phiên bản 4 nếu bạn chạy công cụ này bằng các tham số mặc định. Bạn có thể tắt tính năng ký phiên bản 4 theo cách tương tự như các lược đồ ký khác. Công cụ này cũng có thể xác minh xem chữ ký phiên bản 4 có hợp lệ hay không.
adb yêu cầu tệp .apk.idsig phải nằm bên cạnh APK khi chạy lệnh adb install --incremental. Theo mặc định, adb cũng sử dụng tệp IDSIG để thử cài đặt gia tăng và quay lại quy trình cài đặt thông thường nếu tệp này bị 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 phát trực tiếp mới trong PackageInstaller sẽ chấp nhận chữ ký v4 đã loại bỏ làm đối số riêng khi thêm một tệp vào phiên.
Lúc này, signing_info được truyền vào IncFS dưới dạng một blob hoàn chỉnh. 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ẽ thực hiện một lệnh gọi 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 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 đã được rút gọn được mã hoá dưới dạng Base64 làm tham số cho mỗi tệp được thêm. Merkle tree tương ứng phải được gửi vào stdin của lệnh.
apk_digest
apk_digest là bản tóm tắt nội dung đầu tiên có sẵn theo thứ tự:
- V3, khối 1 MB, SHA2-512 (
CONTENT_DIGEST_CHUNKED_SHA512) - V3, khối 4 KB, SHA2-256 (
CONTENT_DIGEST_VERITY_CHUNKED_SHA256) - V3, khối 1 MB, SHA2-256 (
CONTENT_DIGEST_CHUNKED_SHA256) - V2, SHA2-512
- V2, SHA2-256
Xem chuỗi có tiền tố độ dài của trình ký có tiền tố độ dài trong lược đồ chữ ký APK phiên bản 3.
Xác thực và kiểm thử
Quy trình xác thực APK phiên bản 4 được minh hoạ trong hình sau:

Hình 1. Quy trình xác thực APK phiên bản 4.
Xác thực việc triển khai bằng các 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 thử định dạng chữ ký, hãy thiết lập môi trường bản dựng và chạy các kiểm thử thủ công sau:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Kiểm thử định dạng chữ ký bằng Android SDK (ADB và apksigner)
Sử dụng quy trình này để kiểm thử định dạng chữ ký bằng Android SDK:
- Thiết lập môi trường xây dựng và đảm bảo bạn đã hoàn tất việc triển khai IncFS.
- Nạp bản dựng vào một thiết bị thực hoặc trình mô phỏng mục tiêu.
- Tạo hoặc lấy một APK hiện có rồi tạo một khoá ký gỡ lỗi.
- Ký và cài đặt APK bằng định dạng chữ ký phiên bản 4 trong thư mục build-tools.
Ký
$ ./apksigner sign --ks debug.keystore game.apk
Cài đặt
$ ./adb install game.apk
Nơi bạn có thể tìm thấy các thử nghiệm này
/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java