يدعم Android 9 تدوير مفتاح APK ، والذي يمنح التطبيقات القدرة على تغيير مفتاح التوقيع كجزء من تحديث APK. لجعل التناوب عمليًا ، يجب أن تشير ملفات APK إلى مستويات الثقة بين مفتاح التوقيع الجديد والقديم. لدعم تدوير المفاتيح ، قمنا بتحديث مخطط توقيع APK من الإصدار 2 إلى الإصدار 3 للسماح باستخدام المفاتيح الجديدة والقديمة. يضيف V3 معلومات حول إصدارات SDK المدعومة وبنية إثبات التدوير إلى كتلة توقيع APK.
حظر توقيع APK
للحفاظ على التوافق مع الإصدارات السابقة مع تنسيق v1 APK ، يتم تخزين توقيعات v2 و v3 APK داخل حزمة توقيع APK ، الموجودة مباشرة قبل دليل ZIP المركزي.
تنسيق v3 APK Signing Block هو نفسه v2.0 . يتم تخزين توقيع v3 لملف APK كزوج قيم المعرف بالمعرف 0xf05368c0.
مخطط توقيع APK الإصدار 3 بلوك
تم تصميم مخطط v3 ليكون مشابهًا جدًا لمخطط v2 . له نفس التنسيق العام ويدعم نفس معرفات خوارزمية التوقيع وأحجام المفاتيح ومنحنيات EC.
ومع ذلك ، فإن نظام v3 يضيف معلومات حول إصدارات SDK المدعومة وبنية إثبات التدوير.
شكل
يتم تخزين كتلة مخطط توقيع APK v3 داخل كتلة توقيع APK تحت المعرف 0xf05368c0
.
يتبع تنسيق كتلة APK Signature Scheme v3 تنسيق الإصدار 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 v3 أو نظام v2 أو نظام v1. تتجاهل الأنظمة الأساسية القديمة توقيعات v3 وتحاول التحقق من توقيعات v2 ، ثم v1.
الشكل 1. عملية التحقق من توقيع APK
التحقق من ملف APK Signature Scheme v3
- حدد موقع حظر توقيع APK وتحقق مما يلي:
- يحتوي حقلا الحجمان في كتلة توقيع APK على نفس القيمة.
- ZIP Central Directory يتبعه على الفور ZIP نهاية سجل الدليل المركزي.
- لا يتم تتبع نهاية الدليل المركزي بتنسيق ZIP بمزيد من البيانات.
- حدد موقع كتلة الإصدار 3 من مخطط توقيع APK الأول داخل كتلة توقيع APK. إذا كان الإصدار 3 Block موجودًا ، فانتقل إلى الخطوة 3. وإلا ، فارجع للتحقق من APK باستخدام مخطط v2 .
- لكل
signer
في حزمة APK Signature Scheme v3 مع الحد الأدنى والحد الأقصى لإصدار SDK الموجود في نطاق النظام الأساسي الحالي:- اختر أقوى
signature algorithm ID
المدعومة منsignatures
. يعود ترتيب القوة إلى كل إصدار تنفيذ / نظام أساسي. - تحقق من
signature
المقابل منsignatures
مقابلsigned data
باستخدامpublic key
. (أصبح من الآمن الآن تحليلsigned data
.) - تحقق من تطابق الحد الأدنى والحد الأقصى من إصدارات SDK في البيانات الموقعة مع تلك المحددة
signer
. - تحقق من أن القائمة المرتبة لمعرفات خوارزمية التوقيع في
digests
signatures
متطابقة. (هذا لمنع تجريد / إضافة التوقيع.) - احسب ملخص محتويات APK باستخدام نفس خوارزمية الملخص مثل خوارزمية الملخص المستخدمة بواسطة خوارزمية التوقيع.
- تحقق من أن
digest
المحسوب مطابق للملخص المقابل منdigests
. - تحقق من مطابقة SubjectPublicKeyInfo
certificates
الأولىcertificate
public key
. - إذا كانت سمة إثبات التدوير موجودة
signer
، فتحقق من أن البنية صالحة وأن هذاsigner
هو آخر شهادة في القائمة.
- اختر أقوى
- ينجح التحقق إذا تم العثور على
signer
signer
تصديق
لاختبار أن جهازك يدعم الإصدار 3 بشكل صحيح ، قم بتشغيل اختبارات PkgInstallSignatureVerificationTest.java
CTS في cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.