اندروید 11 از طرح امضای سازگار با جریان با طرح امضای APK نسخه 4 پشتیبانی می کند. امضای v4 بر اساس درخت هش Merkle است که بر روی تمام بایت های APK محاسبه شده است. دقیقاً از ساختار درخت هش fs-verity پیروی می کند (مثلاً نمک را صفر و آخرین بلوک را صفر می کند). Android 11 امضا را در یک فایل جداگانه ذخیره میکند، <apk name>.apk.idsig
امضای v4 به امضای مکمل نسخه 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
، باید دادههای زیر را در باینری 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
کل درخت Merkle APK است که همانطور که در مستندات fs-verity توضیح داده شده محاسبه شده است.
تولید کنندگان و مصرف کنندگان
ابزار Android SDK apksigner
اکنون اگر آن را با پارامترهای پیش فرض اجرا کنید، فایل امضای v4 را تولید می کند. امضای v4 را می توان مانند سایر طرح های امضا غیرفعال کرد. همچنین می تواند تأیید کند که آیا امضای v4 معتبر است یا خیر.
adb
انتظار دارد هنگام اجرای دستور adb install --incremental
فایل .apk.idsig در کنار apk. وجود داشته باشد.
همچنین از فایل idsig برای امتحان نصب افزایشی به طور پیشفرض استفاده میکند و در صورت عدم وجود یا نامعتبر بودن، به یک نصب معمولی برمیگردد.
هنگامی که یک جلسه نصب ایجاد می شود، API نصب جریان جدید در PackageInstaller
هنگام افزودن یک فایل به جلسه، امضای حذف شده v4 را به عنوان یک آرگومان جداگانه می پذیرد. در این مرحله signing_info
به عنوان یک حباب کامل به incfs منتقل میشود. Incfs هش ریشه را از حباب استخراج می کند.
هنگامی که جلسه نصب انجام می شود، PackageManagerService یک ioctl برای بازیابی حباب signing_info
از incfs انجام می دهد، آن را تجزیه می کند و امضا را تأیید می کند.
انتظار میرود که مؤلفه بارگذار داده افزایشی، بخش درخت Merkle از امضا را از طریق API بومی بارگذار داده پخش کند.
دستور install-incremental
پوسته سرویس package
فایل امضای stripped v4 که به عنوان base64 کدگذاری شده است را به عنوان پارامتر برای هر فایل اضافه شده می پذیرد. درخت Merkle مربوطه باید به stdin
فرمان ارسال شود.
apk_digest
apk_digest
اولین خلاصه محتوای موجود به ترتیب است:
- نسخه 3، بلوک 1 مگابایت، SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)،
- V3، بلوک 4KB، SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)،
- نسخه 3، بلوک 1 مگابایت، SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)،
- V2، SHA2-512،
- V2، SHA2-256.
دنباله طول پیشوند امضاهای با پیشوند طول را در طرح امضای APK نسخه 3 ببینید.
اعتبار سنجی و آزمایش
اعتبار پیاده سازی را با استفاده از تست های واحد ویژگی و 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