الإصدار 4 من مخطّط توقيع حزمة APK

يتوافق Android 11 مع نظام توقيع متوافق مع البث مع حِزمة APK. الإصدار 4 من مخطّط التوقيع يعتمد توقيع الإصدار 4 على شجرة تجزئة Merkle. تم احتسابها باستخدام جميع وحدات البايت في حزمة 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 مأخوذ من مجموعة توقيع الإصدار 3 من حزمة APK، أو في حال لم يكن كذلك حاليًا، من الجزء 2 من الإصدار 2 (يُرجى الاطّلاع على apk_QUERY)

لإنشاء رمز 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.

المنتجون والمستهلكون

أداة apksigner Android SDK تنشئ الآن ملف توقيع الإصدار 4 إذا قمت بتشغيله باستخدام المعلمات الافتراضية. يمكن إيقاف توقيع الإصدار 4 بالطريقة نفسها. مثل مخططات التوقيع الأخرى. ويمكنه أيضًا التحقّق مما إذا كان توقيع الإصدار 4 صالحة.

يتوقع adb أن يكون الملف .apk.idsig بجانب ملف .apk عند يتم الآن تشغيل الأمر adb install --incremental
سيستخدم أيضًا ملف .idsig لمحاولة التثبيت الإضافي من خلال وسيعود إلى تثبيت عادي إذا كان مفقودًا أو غير صالح.

واجهة برمجة التطبيقات الجديدة لتثبيت البث عند إنشاء جلسة تثبيت في PackageInstaller تقبل المجرَّد توقيع الإصدار 4 كوسيطة منفصلة عند إضافة ملف إلى الجلسة. في هذه المرحلة، يتم تمرير signing_info إلى incfs كائن ثنائي كبير (blob) كامل. يستخرج Incfs تجزئة الجذر من الكائن الثنائي الكبير (blob).

وأثناء تنفيذ جلسة التثبيت، فإن PackageManagerService ioctl لاسترداد الكائن الثنائي لمعلومات التوقيع (blob) من incfs وتحليله والتحقق من التوقيع.

من المتوقع أن يبث مكوِّن أداة تحميل البيانات الإضافية جزء شجرة Merkle للتوقيع من خلال واجهة برمجة التطبيقات الأصلية لأداة تحميل البيانات.
الأمر package لهيكل الخدمة install-incremental ملف توقيع الإصدار 4 الذي تم اختصاره، والذي تم ترميزه كـ base64 كمعلمة لكل ملف تمت إضافته. ينبغي إرسال شجرة Merkle المقابلة إلى جدول بيانات الأمر stdin

ملف apk_ملخص

apk_digest هو أول ملخّص محتوى متوفّر بالترتيب:

  1. V3، كتلة 1 ميغابايت، SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512)،
  2. V3، كتلة 4 كيلوبايت، SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256)،
  3. V3، كتلة 1 ميغابايت، SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256)،
  4. V2، وSHA2-512،
  5. V2، SHA2-256.

عرض الطول الذي يبدأ ببادئة سلسلة من التوقيعات التي تحمل بادئة طول في الإصدار 3 من مخطّط توقيع حزمة APK

عملية التحقق من حزمة APK - الإصدار 4
الشكل 1: الإصدار 4 من عملية التحقّق من صحة حزمة APK

التحقق من الصحة والاختبار

تحقَّق من صحة التنفيذ باستخدام اختبارات وحدة الميزات وCTS.

  • CtsIncrementalInstallHostTestCases
    • /android/cts/hostsidetests/incrementalinstall

اختبار تنسيق التوقيع

لاختبار تنسيق التوقيع، يمكنك إعداد بيئة تطوير وإجراء الاختبارات اليدوية التالية:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

اختبار تنسيق التوقيع باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android (ADB وapksigner)

لاختبار تنسيق التوقيع باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android، يمكنك إعداد بيئة تطوير. وتتأكد من إكمال تنفيذ IncFS: بعد ذلك، يمكنك تثبيت الإصدار على جهاز فعلي أو محاكي مستهدَف. أنت بحاجة إلى لإنشاء حزمة APK حالية أو الحصول عليها، ثم إنشاء مفتاح توقيع لتصحيح الأخطاء. أخيرًا، وقِّع ملف apk بتنسيق توقيع الإصدار 4 وثبِّته. من مجلد 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