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

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

حظر توقيع APK

للحفاظ على التوافق مع الإصدارات السابقة مع تنسيق v1 APK، يتم تخزين توقيعات v2 وv3 APK داخل كتلة توقيع APK، الموجودة مباشرة قبل دليل ZIP المركزي.

تنسيق v3 APK Signing Block هو نفس تنسيق v2 . يتم تخزين توقيع v3 لـ APK كزوج من قيمة المعرف بالمعرف 0xf05368c0.

كتلة مخطط توقيع APK v3

تم تصميم نظام v3 ليكون مشابهًا جدًا لنظام v2 . له نفس التنسيق العام ويدعم نفس معرفات خوارزمية التوقيع وأحجام المفاتيح ومنحنيات EC.

ومع ذلك، يضيف نظام v3 معلومات حول إصدارات SDK المدعومة وبنية إثبات التغيير.

شكل

يتم تخزين كتلة APK Signature Scheme v3 داخل كتلة توقيع APK تحت المعرف 0xf05368c0 .

يتبع تنسيق APK Signature Scheme v3 Block تنسيق الإصدار 2:

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

بنيات إثبات التناوب والشهادات القديمة الموثوقة ذاتيًا

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

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

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

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

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

شكل

يتم تخزين إثبات التغيير داخل كتلة APK Signature Scheme v3 تحت المعرف 0x3ba06f8c . تنسيقه هو:

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

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

يتعامل Android حاليًا مع APK الموقّع بشهادات متعددة على أنه يمتلك هوية توقيع فريدة منفصلة عن الشهادات المتضمنة. وبالتالي، تشكل سمة إثبات التغيير في قسم البيانات الموقعة رسمًا بيانيًا غير دوري موجه، والذي يمكن عرضه بشكل أفضل كقائمة مرتبطة بشكل فردي، حيث تمثل كل مجموعة من الموقعين لإصدار معين عقدة واحدة. وهذا يضيف تعقيدًا إضافيًا إلى بنية إثبات التغيير (إصدار متعدد التوقيع أدناه). على وجه الخصوص، يصبح الطلب مصدر قلق. علاوة على ذلك، لم يعد من الممكن التوقيع على ملفات APK بشكل مستقل، لأن بنية إثبات التدوير يجب أن تحتوي على شهادات التوقيع القديمة التي توقع على المجموعة الجديدة من الشهادات، بدلاً من التوقيع عليها واحدة تلو الأخرى. على سبيل المثال، ملف APK موقّع بواسطة المفتاح A والذي يرغب في التوقيع بواسطة مفتاحين جديدين B وC لا يمكن أن يتضمن الموقّع B توقيعًا بواسطة A أو B فقط، لأن هذه هوية توقيع مختلفة عن B وC. وهذا من شأنه أن يعني أنه يجب على الموقعين التنسيق قبل بناء مثل هذا الهيكل.

سمة إثبات التغيير للموقّعين المتعددين

  • تسلسل ذو بادئة طول sets ذات البادئة الطول:
    • signed data (حسب المجموعة السابقة - إن وجدت)
      • تسلسل certificates ذات البادئة الطولية
        • certificate X.509 ذات بادئة طولية (نموذج ASN.1 DER)
      • تسلسل signature algorithm IDs (uint32) - واحد لكل شهادة من المجموعة السابقة، بنفس الترتيب.
    • flags (uint32) - أعلام تشير إلى ما إذا كانت مجموعة الشهادات هذه يجب أن تكون موجودة في بنية الشهادات القديمة الموثوقة ذاتيًا أم لا، وما هي العمليات الخاصة بها.
    • تسلسل مسبوق بالطول من signatures مسبوقة بالطول :
      • signature algorithm ID (uint32) - يجب أن يتطابق مع المعرف الموجود في قسم البيانات الموقعة
      • signature ببادئة الطول فوق signed data أعلاه

أسلاف متعددة في بنية إثبات التناوب

لا يتعامل نظام v3 أيضًا مع مفتاحين مختلفين يدوران على نفس مفتاح التوقيع لنفس التطبيق. ويختلف هذا عن حالة الاستحواذ، حيث ترغب الشركة المستحوذة في نقل التطبيق المكتسب لاستخدام مفتاح التوقيع الخاص به لمشاركة الأذونات. يُنظر إلى عملية الاستحواذ على أنها حالة استخدام مدعومة لأن التطبيق الجديد سيتم تمييزه باسم الحزمة الخاصة به ويمكن أن يحتوي على بنية إثبات التدوير الخاصة به. الحالة غير المدعومة، لنفس التطبيق الذي يحتوي على مسارين مختلفين للوصول إلى نفس الشهادة، تنتهك الكثير من الافتراضات التي تم وضعها في تصميم تدوير المفاتيح.

تَحَقّق

في Android 9 والإصدارات الأحدث، يمكن التحقق من ملفات APK وفقًا لنظام APK Signature Scheme v3 أو v2 أو مخطط v1. تتجاهل الأنظمة الأساسية الأقدم توقيعات v3 وتحاول التحقق من توقيعات v2، ثم v1.

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

الشكل 1. عملية التحقق من توقيع APK

التحقق من نظام توقيع APK v3

  1. حدد موقع كتلة توقيع APK وتحقق مما يلي:
    1. يحتوي حقلا حجم APK Signing Block على نفس القيمة.
    2. يتبع ZIP Central Directory مباشرة سجل ZIP End of Central Directory.
    3. ZIP End of Central Directory لا يتبعه المزيد من البيانات.
  2. حدد موقع أول كتلة APK Signature Scheme v3 داخل كتلة توقيع APK. في حالة وجود كتلة v3، انتقل إلى الخطوة 3. وإلا، فارجع إلى التحقق من APK باستخدام مخطط v2 .
  3. لكل signer في كتلة APK Signature Scheme v3 مع الحد الأدنى والحد الأقصى لإصدار 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/ .