طرح امضای APK نسخه 4

اندروید 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;
};
  1. 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 اولین خلاصه محتوای موجود به ترتیب است:

  1. نسخه 3، بلوک 1 مگابایت، SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)،
  2. V3، بلوک 4KB، SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)،
  3. نسخه 3، بلوک 1 مگابایت، SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)،
  4. V2، SHA2-512،
  5. V2، SHA2-256.

دنباله طول پیشوند امضاهای با پیشوند طول را در طرح امضای APK نسخه 3 ببینید.

فرآیند اعتبار سنجی apk v4
شکل 1 : فرآیند اعتبار سنجی APK نسخه 4

اعتبار سنجی و آزمایش

اعتبار پیاده سازی را با استفاده از تست های واحد ویژگی و 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