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

APK Signature Scheme v2 هو مخطط توقيع كامل للملف يزيد من سرعة التحقق ويعزز ضمانات السلامة من خلال اكتشاف أي تغييرات في الأجزاء المحمية من APK.

يؤدي التوقيع باستخدام APK Signature Scheme v2 إلى إدراج حظر توقيع APK في ملف APK قبل قسم الدليل المركزي ZIP مباشرة. داخل كتلة توقيع APK ، يتم تخزين تواقيع الإصدار 2 ومعلومات هوية المُوقِّع في كتلة APK Signature Scheme v2 .

APK قبل وبعد التوقيع

الشكل 1. APK قبل التوقيع وبعده

تم تقديم APK Signature Scheme v2 في Android 7.0 (Nougat). لجعل APK قابلاً للتثبيت على Android 6.0 (Marshmallow) والأجهزة الأقدم ، يجب توقيع APK باستخدام توقيع JAR قبل توقيعه باستخدام نظام v2.

حظر توقيع APK

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

تحتوي الكتلة على أزواج قيمة المعرف ملفوفة بطريقة تسهل تحديد موقع الكتلة في APK. يتم تخزين توقيع v2 لملف APK كزوج قيم المعرف بالمعرف 0x7109871a.

شكل

تنسيق APK Signing Block هو كما يلي (جميع الحقول الرقمية صغيرة):

  • size of block بالبايت (باستثناء هذا الحقل) (uint64)
  • تسلسل أزواج قيمة معرّف uint64 ذات الطول المسبق:
    • ID (uint32)
    • value (متغير الطول: طول الزوج - 4 بايت)
  • size of block بالبايت - نفس الحقل الأول (uint64)
  • magic “APK Sig Block 42” (16 بايت)

يتم تحليل APK من خلال إيجاد بداية الدليل المركزي ZIP أولاً (من خلال إيجاد ZIP End of Central Directory Record في نهاية الملف ، ثم قراءة إزاحة البداية للدليل المركزي من السجل). توفر القيمة magic طريقة سريعة لإثبات أن ما يسبق الدليل المركزي هو على الأرجح كتلة توقيع APK. ثم يشير size of block بكفاءة إلى بداية الكتلة في الملف.

يجب تجاهل أزواج قيمة المعرف ذات المعرفات غير المعروفة عند تفسير الكتلة.

مخطط توقيع APK الإصدار 2 بلوك

تم توقيع APK بواسطة موقع / هوية واحد أو أكثر ، يتم تمثيل كل منها بمفتاح توقيع. يتم تخزين هذه المعلومات ككتلة v2 لمخطط توقيع APK. لكل موقع ، يتم تخزين المعلومات التالية:

  • (خوارزمية التوقيع ، الملخص ، التوقيع). يتم تخزين الملخص لفصل التحقق من صحة التوقيع عن التحقق من سلامة محتويات APK.
  • سلسلة شهادات X.509 تمثل هوية الموقّع.
  • سمات إضافية كأزواج مفتاح-قيمة.

لكل موقع ، يتم التحقق من APK باستخدام توقيع معتمد من القائمة المقدمة. يتم تجاهل التوقيعات ذات الخوارزميات غير المعروفة. الأمر متروك لكل تطبيق لاختيار التوقيع الذي سيتم استخدامه عند مواجهة العديد من التواقيع المدعومة. يتيح ذلك تقديم أساليب توقيع أقوى في المستقبل بطريقة متوافقة مع الإصدارات السابقة. النهج المقترح هو التحقق من أقوى توقيع.

شكل

يتم تخزين كتلة مخطط توقيع APK v2 داخل كتلة توقيع APK تحت المعرف 0x7109871a .

صيغة APK Signature Scheme v2 Block هي كما يلي (جميع القيم الرقمية صغيرة ، جميع الحقول ذات الطول تستخدم uint32 للطول):

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

معرفات خوارزمية التوقيع

  • 0x0101 - RSASSA-PSS مع SHA2-256 Digest ، SHA2-256 MGF1 ، 32 بايت من الملح ، المقطورة: 0xbc
  • 0x0102 - RSASSA-PSS مع SHA2-512 Digest ، SHA2-512 MGF1 ، 64 بايت من الملح ، المقطورة: 0xbc
  • 0x0103 — RSASSA-PKCS1-v1_5 مع ملخص SHA2-256. هذا لأنظمة البناء التي تتطلب تواقيع حتمية.
  • 0x0104 — RSASSA-PKCS1-v1_5 مع ملخص SHA2-512. هذا لأنظمة البناء التي تتطلب تواقيع حتمية.
  • 0x0201— ECDSA بهضم SHA2-256
  • 0x0202— ECDSA مع ملخص SHA2-512
  • 0x0301 — DSA مع ملخص SHA2-256

يتم دعم جميع خوارزميات التوقيع أعلاه بواسطة نظام Android الأساسي. قد تدعم أدوات التوقيع مجموعة فرعية من الخوارزميات.

أحجام المفاتيح المدعومة ومنحنيات EC:

  • RSA: 1024 ، 2048 ، 4096 ، 8192 ، 16384
  • EC: NIST P-256 ، P-384 ، P-521
  • DSA: 1024 ، 2048 ، 3072

محتويات محمية من النزاهة

لأغراض حماية محتويات APK ، يتكون APK من أربعة أقسام:

  1. محتويات إدخالات ZIP (من الإزاحة 0 حتى بداية حظر توقيع APK)
  2. حظر توقيع APK
  3. دليل ZIP المركزي
  4. ZIP نهاية الدليل المركزي

أقسام APK بعد التوقيع

الشكل 2. أقسام APK بعد التوقيع

يحمي APK Signature Scheme v2 سلامة الأقسام 1 و 3 و 4 وكتل signed data من حزمة APK Signature Scheme v2 الموجودة داخل القسم 2.

سلامة الأقسام 1 و 3 و 4 محمية بواحد أو أكثر من ملخصات محتوياتها المخزنة في كتل signed data والتي بدورها محمية بتوقيع واحد أو أكثر.

يتم حساب الملخص على الأقسام 1 و 3 و 4 على النحو التالي ، على غرار شجرة Merkle ذات المستويين. يتم تقسيم كل قسم إلى أجزاء متتالية بحجم 1 ميغا بايت (2 20 بايت). قد تكون القطعة الأخيرة في كل قسم أقصر. يتم حساب ملخص كل قطعة على تسلسل البايت 0xa5 ، وطول القطعة بالبايت (little endian uint32) ، ومحتويات القطعة. يتم حساب ملخص المستوى الأعلى عبر تسلسل البايت 0x5a ، وعدد القطع (little endian uint32) ، وتسلسل ملخصات الأجزاء بالترتيب الذي تظهر به القطع في ملف APK. يتم حساب الملخص بطريقة مجزأة لتمكين تسريع الحساب عن طريق موازنته.

ملخص APK

الشكل 3. ملخص APK

حماية القسم 4 (ZIP End of Central Directory) معقدة بسبب القسم الذي يحتوي على إزاحة الدليل المركزي ZIP. يتغير الإزاحة عندما يتغير حجم حزمة توقيع APK ، على سبيل المثال ، عند إضافة توقيع جديد. وبالتالي ، عند حساب الملخص عبر ZIP End of Central Directory ، يجب التعامل مع الحقل الذي يحتوي على إزاحة دليل ZIP المركزي على أنه يحتوي على إزاحة كتلة توقيع APK.

حماية التراجع

قد يحاول المهاجم الحصول على ملف APK موقّع على الإصدار 2 تم التحقق منه باعتباره ملف APK موقع v1 على أنظمة Android الأساسية التي تدعم التحقق من APK v2 الموقع. للتخفيف من هذا الهجوم ، يجب أن تحتوي ملفات APK الموقعة v2 والموقعة أيضًا على v1 على سمة X-Android-APK-Signed في القسم الرئيسي من ملفات META-INF / *. SF الخاصة بهم. قيمة السمة عبارة عن مجموعة مفصولة بفواصل من معرفات مخطط توقيع APK (معرف هذا المخطط هو 2). عند التحقق من توقيع v1 ، يلزم التحقق من APK لرفض ملفات APK التي لا تحتوي على توقيع لنظام توقيع APK الذي يفضله المدقق من هذه المجموعة (على سبيل المثال ، مخطط v2). تعتمد هذه الحماية على حقيقة أن محتويات ملفات META-INF / *. SF محمية بتوقيعات v1. راجع القسم الخاص بالتحقق من ملف APK الموقع من JAR .

قد يحاول المهاجم إزالة التواقيع الأقوى من حزمة APK Signature Scheme v2 Block. للتخفيف من هذا الهجوم ، يتم تخزين قائمة معرفات خوارزمية التوقيع التي تم توقيع APK من خلالها في كتلة signed data والمحمية بكل توقيع.

تَحَقّق

في الإصدار Android 7.0 والإصدارات الأحدث ، يمكن التحقق من ملفات APK وفقًا لنظام توقيع APK v2 + أو توقيع JAR (نظام v1). تتجاهل الأنظمة الأساسية القديمة تواقيع الإصدار 2 وتتحقق فقط من توقيعات الإصدار 1.

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

الشكل 4. عملية التحقق من توقيع APK (خطوات جديدة باللون الأحمر)

التحقق من ملف APK Signature Scheme v2

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

ملاحظة : يجب عدم التحقق من APK باستخدام مخطط v1 في حالة حدوث فشل في الخطوة 3 أو 4.

التحقق من ملف APK بتوقيع JAR (مخطط الإصدار 1)

ملف APK الموقّع من JAR هو ملف JAR قياسي موقّع ، يجب أن يحتوي بالضبط على الإدخالات المدرجة في META-INF / MANIFEST.MF وحيث يجب توقيع جميع الإدخالات بواسطة نفس مجموعة الموقّعين. يتم التحقق من سلامتها على النحو التالي:

  1. يتم تمثيل كل موقع بواسطة إدخال META-INF / <signer> .SF و META-INF / <signer>. (RSA | DSA | EC) JAR.
  2. <signer>. (RSA | DSA | EC) هو PKCS # 7 CMS ContentInfo بهيكل SignedData الذي تم التحقق من توقيعه عبر الملف <signer> .SF.
  3. يحتوي ملف <signer> .SF على ملخص كامل للملف META-INF / MANIFEST.MF وملخصات كل قسم من META-INF / MANIFEST.MF. تم التحقق من ملخص الملف بالكامل MANIFEST.MF. إذا فشل ذلك ، فسيتم التحقق من ملخص كل قسم من أقسام MANIFEST.MF بدلاً من ذلك.
  4. يحتوي META-INF / MANIFEST.MF ، لكل إدخال JAR محمي بالسلامة ، على قسم يحمل اسمًا مطابقًا يحتوي على ملخص محتويات الإدخال غير المضغوطة. تم التحقق من كل هذه الملخصات.
  5. يفشل التحقق من ملف APK إذا كان ملف APK يحتوي على إدخالات JAR غير المدرجة في MANIFEST.MF وليست جزءًا من توقيع JAR.

وبالتالي فإن سلسلة الحماية هي <signer>. (RSA | DSA | EC) -> <signer> .SF -> MANIFEST.MF -> محتويات كل إدخال JAR محمي من حيث السلامة.