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

يتيح نظام التشغيل Android 9 تغيير مفاتيح ملف APK، ما يمنح التطبيقات إمكانية تغيير مفتاح التوقيع كأحد أجزاء تحديث حزمة APK. لتسهيل عملية التغيير، يجب أن تشير حِزم APK إلى مستويات الثقة بين مفتاح التوقيع الجديد والقديم. ولتفعيل ميزة تغيير المفاتيح، عدّلنا مخطّط توقيع APK من الإصدار 2 إلى الإصدار 3 للسماح باستخدام المفاتيح الجديدة والقديمة. يضيف الإصدار 3 معلومات عن إصدارات حزمة SDK المتوافقة وبنية لإثبات التبديل إلى وحدة توقيع APK.

حظر توقيع حِزم APK

للحفاظ على التوافق مع الإصدارات القديمة من تنسيق APK، يتم تخزين توقيعات APK من الإصدارَين 2 و3 داخل كتلة توقيع APK، والتي تقع مباشرةً قبل ملف ZIP Central Directory.

ويكون تنسيق مجموعة توقيع حزمة APK v3 هو نفس تنسيق الإصدار 2. يتم تخزين توقيع الإصدار 3 من حزمة APK كزوج مكوّن من معرّف وقيمة بمعرّف 0xf05368c0.

حظر الإصدار 3 من مخطّط توقيع حِزم APK

تم تصميم مخطّط الإصدار 3 ليشبه إلى حد كبير مخطّط الإصدار 2. وهو يتضمّن التنسيق العام نفسه ويتوافق مع معرّفات ملفّات توقيع الترميز وحجم المفاتيح ومنحنيات الإحالة الناجحة للخوارزمية نفسها.

ومع ذلك، يضيف مخطّط الإصدار 3 معلومات عن إصدارات حِزم تطوير البرامج (SDK) المتوافقة وبنية إثبات التدوير.

التنسيق

يتم تخزين الإصدار 3 من مخطّط توقيع حزمة APK داخل كتلة توقيع حزمة APK ضمن المعرّف 0xf05368c0.

يتّبع تنسيق الإصدار 3 من مخطّط توقيع حزمة APK تنسيق الإصدار 2:

  • تسلسل مسبوق بطول من signer مسبوق بطول:
    • signed data التي تحتوي على بادئة الطول:
      • تسلسل مسبوق بطول من digests مسبوق بطول:
        • signature algorithm ID (4 بايت)
        • digest (مسبوقة بطول)
      • تسلسل مسبوق بطول X.509 certificates:
        • certificate‏X.509 مسبوقة بطول certificate (تنسيق ASN.1 DER)
      • minSDK (uint32) - يجب تجاهل هذا الموقّع إذا كان إصدار النظام الأساسي أقل من هذا الرقم.
      • maxSDK (uint32) - يجب تجاهل هذا الموقّع إذا كان إصدار النظام الأساسي أعلى من هذا الرقم.
      • تسلسل مسبوق بطول من additional attributes مسبوق بطول:
        • ID (uint32)
        • value (طول متغيّر: طول السمة الإضافية - 4 بايت)
        • ID - 0x3ba06f8c
        • value - بنية صلاحية التغيير
    • minSDK (uint32) - نسخة طبق الأصل من قيمة minSDK في قسم data signed ، وتُستخدَم لتخطّي عملية التحقّق من هذا التوقيع إذا كان النظام الأساسي الحالي ليس ضمن النطاق. يجب أن تتطابق مع قيمة البيانات الموقَّعة.
    • maxSDK (uint32) - نسخة طبق الأصل من قيمة maxSDK في قسم data الموقَّع - تُستخدَم لتخطّي عملية التحقّق من هذا التوقيع إذا لم يكن النظام الأساسي الحالي ضمن النطاق. يجب أن تتطابق مع قيمة البيانات الموقَّعة.
    • تسلسل مسبوق بطول من signatures مسبوق بطول:
      • signature algorithm ID (uint32)
      • signature مسبوقة بطولها على signed data
    • public key مسبوقة بطول (SubjectPublicKeyInfo، تنسيق ASN.1 DER )

بنية صلاحية التغيير وبنية self-trusted-old-certs

تسمح بنية إثبات التبديل للتطبيقات بتبديل شهادة التوقيع الخاصة بها بدون حظرها على التطبيقات الأخرى التي تتواصل معها. ولإجراء ذلك، تحتوي ملفّات توقيع التطبيق على قطعتَين جديدتَين من البيانات:

  • تأكيد لجهات خارجية بأنّه يمكن الوثوق بشهادة توقيع التطبيق في حال كانت الشهادات السابقة موثوق بها
  • شهادات التوقيع القديمة للتطبيق التي لا يزال التطبيق نفسه يثق بها

تتألف سمة إثبات التدوير في قسم البيانات الموقَّعة من قائمة مرتبطة برابط واحد، تحتوي كل عقدة فيها على شهادة توقيع تم استخدامها لتوقيع الإصدارات السابقة من التطبيق. ومن المفترض أن تحتوي هذه السمة على هياكل بيانات إثبات التدوير والشهادات القديمة الموثوق بها ذاتيًا. يتم ترتيب القائمة حسب الإصدار مع أقدم شهادة توقيع تتوافق مع عقدة الجذر. يتم إنشاء بنية بيانات إثبات التدوير من خلال جعل الشهادة في كل عقدة توقع الشهادة التالية في القائمة، وبالتالي إضفاء دليل على كل مفتاح جديد يفيد بأنّه يجب أن يكون موثوقًا به مثل المفاتيح القديمة.

يتم إنشاء بنية بيانات self-trusted-old-certs من خلال إضافة علامات إلى كل عقدة تشير إلى عضويتها وخصائصها في المجموعة. على سبيل المثال، قد تكون هناك علامة تشير إلى أنّ شهادة التوقيع في عقدة معيّنة موثوقة للحصول على أذونات توقيع Android. تسمح هذه العلامة للتطبيقات الأخرى الموقَّعة بالشهادة القديمة بمواصلة الحصول على إذن التوقيع الذي يحدّده تطبيق موقَّع بالشهادة الجديدة للتوقيع. بما أنّ سمة proof-of-rotation بالكامل موجودة في قسم البيانات الموقَّعة من حقل v3 signer، يتم حمايتها بالمفتاح المستخدَم لتوقيع حِزمة apk التي تحتوي عليها.

يمنع هذا التنسيق استخدام مفاتيح توقيع متعددة ودمج شهادات توقيع مختلفة للسلف في شهادة واحدة (عدة عقد بداية إلى وجهة مشتركة).

التنسيق

يتم تخزين إثبات التغيير داخل حزمة الإصدار 3 من مخطّط توقيع حزمة APK ضمن رقم التعريف 0x3ba06f8c. التنسيق هو:

  • تسلسل مسبوق بطول من levels مسبوق بطول:
    • signed data مسبوقة بطول (حسب الشهادة السابقة، إن توفّرت)
      • certificate‏X.509 مسبوقة بطول certificate (تنسيق ASN.1 DER)
      • signature algorithm ID (uint32) - الخوارزمية المستخدَمة في الشهادة في المستوى السابق
    • flags (uint32) - علامات تشير إلى ما إذا كان يجب أن يكون هذا الشهادة في بنية self-trusted-old-certs أم لا، وعملياتها
    • signature algorithm ID (uint32) - يجب أن تتطابق مع القيمة الواردة في قسم البيانات الموقَّعة في المستوى التالي.
    • signature التي تحتوي على بادئة الطول فوق signed data أعلاه

شهادات متعددة

لا يُسمح بتوقيعات متعددة، ولا ينشر Google Play التطبيقات الموقَّعة باستخدام شهادات متعددة.

إثبات الملكية

في الإصدار 9 من نظام التشغيل Android والإصدارات الأحدث، يمكن التحقّق من حِزم APK وفقًا للإصدار 3 أو 2 أو 1 من مخطّط توقيع حِزم APK. تتجاهل الأنظمة الأساسية القديمة توقيعات الإصدار 3 وتحاول إثبات صحة توقيعات الإصدار 2، ثم الإصدار 1.

عملية التحقّق من توقيع حزمة APK

الشكل 1: عملية التحقّق من توقيع حزمة APK

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

  1. حدِّد موقع مجموعة توقيع APK وتأكَّد مما يلي:
    1. يحتوي حقلَا الحجم الخاصَّان بوحدة توقيع APK على القيمة نفسها.
    2. يتبع "الدليل المركزي" في ملف ZIP على الفور سجلّ "نهاية الدليل المركزي" في ملف ZIP.
    3. لا يتبع رمز ZIP الخاص بنهاية الدليل المركزي المزيد من البيانات.
  2. حدِّد موقع أول كتلة من الإصدار 3 من مخطّط توقيع حزمة APK داخل كتلة توقيع حزمة APK. إذا كان الإصدار 3 من الحزمة متوفّرًا، انتقِل إلى الخطوة 3. بخلاف ذلك، يمكنك الرجوع إلى التحقّق من حزمة APK باستخدام مخطط الإصدار 2.
  3. لكل signer في حزمة APK من الإصدار 3 من مخطّط توقيع الحزمة مع الحد الأدنى والحد الأقصى لإصدار حزمة SDK ضمن نطاق النظام الأساسي الحالي:
    1. اختَر signature algorithm ID الأقوى المتاح من signatures. يعتمد ترتيب مستويات الأمان على كل إصدار من التنفيذ/النظام الأساسي.
    2. تحقّق من signature المطابق من signatures مقابل signed data باستخدام public key. (أصبح من الآمن الآن تحليل signed data.)
    3. تأكَّد من أنّ الحد الأدنى والحد الأقصى لإصدارات حزمة تطوير البرامج (SDK) في البيانات الموقَّعة يتطابقان مع الإصدارَين المحدّدَين لـ signer.
    4. تأكَّد من أنّ القائمة المرتبة لأرقام تعريف خوارزميات التوقيع في digests وsignatures متطابقة. (يتم ذلك لمنع إزالة التوقيع أو إضافته).
    5. احتساب خلاصة محتوى حزمة APK باستخدام خوارزمية الخلاصة نفسها المستخدَمة في خوارزمية التوقيع
    6. تأكَّد من أنّ الملخّص المحسوب مطابق لملف العميل المعني digest من digests.
    7. تأكَّد من أنّ SubjectPublicKeyInfo لأول certificate من certificates مطابقة لـ public key.
    8. إذا كانت سمة إثبات التدوير متوفّرة لشهادة signer، تأكَّد من أنّ البنية صالحة وأنّ signer هي الشهادة الأخيرة في القائمة.
  4. تنجح عملية التحقّق إذا تم العثور على signer واحد بالضبط في النطاق من النظام الأساسي الحالي ونجحت الخطوة 3 لهذا signer.

التحقُّق

لاختبار توافق جهازك مع الإصدار 3 بشكل صحيح، يمكنك إجراء PkgInstallSignatureVerificationTest.java اختبارات CTS في cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.