Android 11 поддерживает схему подписи, совместимую с потоковой передачей, со схемой подписи APK v4. Подпись v4 основана на хеш-дереве Меркла, рассчитанном по всем байтам APK. Он точно соответствует структуре хеш-дерева fs-verity (например, заполнение нулями соли и заполнение нулями последнего блока). Android 11 хранит подпись в отдельном файле <apk name>.apk.idsig
Для подписи версии 4 требуется дополнительная подпись версии 2 или 3 .
Формат файла
Все числовые поля имеют прямой порядок байтов. Все поля занимают ровно столько байтов, сколько их 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
берется из блока подписи v3 APK или, если он отсутствует, из блока v2 (см. apk_digest ).
Для создания и проверки кода signature
необходимо сериализовать следующие данные в двоичный объект и передать их в алгоритм подписи/проверки в качестве подписанных данных :
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, рассчитанное, как описано в документации fs-verity .
Производители и потребители
Инструмент apksigner
Android SDK теперь генерирует файл подписи v4, если вы запускаете его с параметрами по умолчанию. Подпись v4 можно отключить так же, как и другие схемы подписи. Он также может проверить, действительна ли подпись v4.
adb
ожидает, что файл .apk.idsig будет присутствовать рядом с .apk при запуске команды adb install --incremental
Он также будет использовать файл .idsig для попытки добавочной установки по умолчанию и вернется к обычной установке, если он отсутствует или недействителен.
При создании сеанса установки новый API потоковой установки в PackageInstaller
принимает удаленную подпись v4 в качестве отдельного аргумента при добавлении файла в сеанс. На этом этапе signing_info
передается в incfs как целый большой двоичный объект. Incfs извлекает корневой хеш из большого двоичного объекта.
Во время фиксации сеанса установки PackageManagerService выполняет ioctl для получения большого двоичного объекта signing_info
из incfs, анализирует его и проверяет подпись.
Ожидается, что компонент добавочного загрузчика данных будет передавать часть подписи в виде дерева Меркла через собственный API-интерфейс загрузчика данных.
Команда оболочки службы package
install-incremental
принимает удаленный файл подписи v4, закодированный как base64, в качестве параметра для каждого добавленного файла. Соответствующее дерево Меркла должно быть отправлено в stdin
команды.
apk_digest
apk_digest
— это первый доступный дайджест контента по порядку:
- V3, блок 1 МБ, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, блок 4 КБ, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, блок 1 МБ, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
- В2, ША2-512,
- В2, ША2-256.
См . последовательность подписей с префиксом длины в схеме подписи APK v3.
Валидация и тестирование
Проверьте реализацию с помощью Feature Unit Tests и CTS.
-
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
Проверьте формат подписи
Чтобы протестировать формат подписи, настройте среду разработки и запустите следующие ручные тесты:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Проверьте формат подписи с помощью Android SDK (ADB и apksigner)
Чтобы протестировать формат подписи с помощью Android SDK, настройте среду разработки и убедитесь, что вы завершили внедрение IncFS . Затем прошейте сборку на целевом физическом устройстве или эмуляторе. Вам необходимо сгенерировать или получить существующий APK, а затем создать ключ подписи отладки . Наконец, подпишите и установите APK с форматом подписи v4 из папки 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