يتوافق نظام التشغيل Android 11 مع مخطّط توقيع متوافق مع البث باستخدام الإصدار 4 من مخطّط توقيع حِزم APK. يستند التوقيع بالإصدار 4 إلى شجرة تجزئة Merkle
التي يتم احتسابها على جميع وحدات البايت في حزمة APK. يتّبع المخطط بنية شجرة التجزئة fs-verity تمامًا (على سبيل المثال، إضافة أصفار إلى بداية قيمة التجزئة وإضافة أصفار إلى نهاية آخر كتلة). يخزّن نظام التشغيل Android 11 التوقيع
في ملف منفصل، <apk name>.apk.idsig. يتطلّب التوقيع بالإصدار 4 توقيعًا تكميليًا بالإصدار 2 أو 3.
تنسيق الملف
تكون جميع الحقول الرقمية بتنسيق little 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 من قسم التوقيع الإصدار 3 لحزمة 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.
المنتجون والمستهلكون
تنشئ أداة apksigner Android SDK ملف التوقيع بالإصدار 4
إذا نفّذتها باستخدام المَعلمات التلقائية. يمكنك إيقاف التوقيع باستخدام الإصدار 4 بالطريقة نفسها التي يتم بها إيقاف أنظمة التوقيع الأخرى. يمكن للأداة أيضًا التحقّق مما إذا كانت توقيع الإصدار 4 صالحًا.
يتوقّع adb أن يكون الملف .apk.idsig متوفّرًا بجانب حزمة APK عند تنفيذ الأمر adb install --incremental. يستخدم adb أيضًا ملف IDSIG
لتجربة التثبيت التزايدي تلقائيًا، ويعود إلى التثبيت العادي في حال كان الملف
مفقودًا أو غير صالح.
عند إنشاء جلسة تثبيت، تقبل واجهة برمجة التطبيقات الجديدة الخاصة بالتثبيت أثناء البث
في PackageInstaller توقيع الإصدار 4 المجرّد
كوسيطة منفصلة عند إضافة ملف إلى الجلسة.
في هذه المرحلة، يتم تمرير signing_info إلى IncFS ككائن ثنائي كبير الحجم. تستخرج IncFS تجزئة الجذر من الكائن الثنائي الكبير.
عندما يتم تنفيذ جلسة التثبيت، يرسل PackageManagerService طلب ioctl لاسترداد كائن signing_info الثنائي الكبير (blob) من IncFS، ويحلّله، ويتحقّق من التوقيع.
يبث مكوّن Incremental Data Loader جزء شجرة Merkle من التوقيع من خلال واجهة برمجة التطبيقات الأصلية لأداة تحميل البيانات. يقبل packageأمر shell الخاص بالخدمة install-incremental ملف توقيع v4 الذي تمت إزالة مساحاته البيضاء والمشفّر بتنسيق Base64 كمعلَمة لكل ملف تمت إضافته. يجب إرسال شجرة Merkle المقابلة إلى stdin الخاص بالأمر.
apk_digest
apk_digest هي أول خلاصة محتوى متاحة بالترتيب:
- الإصدار 3، حجم الحزمة 1 ميغابايت، خوارزمية SHA2-512 (
CONTENT_DIGEST_CHUNKED_SHA512) - الإصدار 3، كتلة بحجم 4 كيلوبايت، خوارزمية SHA2-256 (
CONTENT_DIGEST_VERITY_CHUNKED_SHA256) - الإصدار 3، حجم الحزمة 1 ميغابايت، خوارزمية SHA2-256 (
CONTENT_DIGEST_CHUNKED_SHA256) - الإصدار 2، SHA2-512
- الإصدار 2، SHA2-256
راجِع تسلسل الموقّع الذي يسبقه الطول في الإصدار 3 من مخطّط توقيع حزمة APK.
التحقّق من صحة الإجراءات واختبارها
يوضّح الشكل التالي عملية التحقّق من صحة حزمة APK الإصدار 4:

الشكل 1: عملية التحقّق من صحة حِزم APK الإصدار 4
تحقَّق من صحة التنفيذ باستخدام اختبارات الوحدات الخاصة بالميزات وCTS:
CtsIncrementalInstallHostTestCases/android/cts/hostsidetests/incrementalinstall
اختبار تنسيق التوقيع
لاختبار تنسيق التوقيع، اضبط بيئة إنشاء ونفِّذ الاختبارات اليدوية التالية:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
اختبار تنسيق التوقيع باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android (أداة تصحيح أخطاء Android وأداة apksigner)
استخدِم هذه العملية لاختبار تنسيق التوقيع باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android:
- إعداد بيئة إنشاء والتأكّد من إكمال عملية تنفيذ 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