مخطط توقيع APK v4.0

يدعم Android 11 مخطط توقيع متوافق مع البث باستخدام APK Signature Scheme v4.1. يعتمد توقيع v4 على شجرة تجزئة Merkle المحسوبة على جميع وحدات بايت ملف APK. يتبع هيكل شجرة تجزئة fs-verity بالضبط (على سبيل المثال ، حشوة صفرية للملح وعدم حشو الكتلة الأخيرة). يخزن Android 11 التوقيع في ملف منفصل ، <apk name>.apk.idsig يتطلب توقيع v4 توقيعًا تكميليًا v2 أو v3 .

تنسيق الملف

جميع الحقول الرقمية مكتوبة بخط Endian الصغير. تشغل جميع الحقول عدد البايتات بالضبط مثل 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 مأخوذ من كتلة توقيع APK v3 ، أو من كتلة 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 .

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

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

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

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

عندما يتم الالتزام بجلسة التثبيت ، تقوم PackageManagerService بعمل ioctl لاسترداد blob signature_info من incfs ، ثم يوزعها ويتحقق من التوقيع.

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

apk_digest

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

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

انظر تسلسل طول مسبوق للتوقيعات مسبوقة الطول في APK Signature Scheme v3.

عملية التحقق من صحة apk v4.0.0
الشكل 1 : عملية التحقق من APK v4.1

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

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

  • CtsIncrementalInstallHostTestCases
    • / android / cts / hostsidetests / incrementalinstall

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

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

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

اختبار تنسيق التوقيع باستخدام Android SDK (ADB و apksigner)

لاختبار تنسيق التوقيع باستخدام Android SDK ، قم بإعداد بيئة تطوير وتأكد من إكمال تنفيذ IncFS . ثم قم بعمل فلاش للبناء على جهاز مادي مستهدف أو محاكي. تحتاج إلى إنشاء ملف APK موجود أو الحصول عليه ثم إنشاء مفتاح توقيع تصحيح الأخطاء . أخيرًا ، قم بتوقيع وتثبيت apk بتنسيق توقيع v4 من مجلد أدوات البناء.

إشارة

$ ./apksigner sign --ks debug.keystore game.apk

تثبيت

$ ./adb install game.apk

أين يمكن العثور على هذه الاختبارات؟

/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java