تستخدِم صور نظام التشغيل Android توقيعات مشفَّرة في مكانَين:
- يجب أن يكون كل ملف
.apk
داخل الصورة موقَّعًا. يستخدم مدير حزم Android توقيع.apk
بطريقتَين:- عند استبدال تطبيق ما، يجب توقيعه باستخدام المفتاح نفسه المُستخدَم في التطبيق القديم من أجل الوصول إلى بيانات التطبيق القديم. وينطبق ذلك
على حد سواء عند تحديث تطبيقات المستخدمين من خلال استبدال
.apk
، وعند استبدال تطبيق نظام بإصدار أحدث تم تثبيته ضمن/data
. - إذا أرادت تطبيقان أو أكثر مشاركة معرّف مستخدم (كي يتمكّنوا من مشاركة data وغيرها)، يجب توقيعهما باستخدام المفتاح نفسه.
- عند استبدال تطبيق ما، يجب توقيعه باستخدام المفتاح نفسه المُستخدَم في التطبيق القديم من أجل الوصول إلى بيانات التطبيق القديم. وينطبق ذلك
على حد سواء عند تحديث تطبيقات المستخدمين من خلال استبدال
- يجب توقيع حِزم التحديثات عبر الهواء باستخدام أحد المفاتيح المتوقّعة من النظام، وإلا سترفض عملية التثبيت هذه الحِزم.
مفاتيح الإصدار
تتضمّن شجرة Android مفاتيح الاختبار ضمن
build/target/product/security
. سيؤدي إنشاء صورة نظام التشغيل Android
باستخدام make
إلى توقيع جميع ملفات .apk
باستخدام
المفاتيح الاختبارية. بما أنّ مفاتيح الاختبار معروفة للجميع، يمكن لأي شخص توقيع ملفاته الخاصة
.apk باستخدام المفاتيح نفسها، ما قد يسمح له باستبدال
تطبيقات النظام المضمّنة في صورة نظام التشغيل أو الاستيلاء عليها. لهذا السبب، من المهم توقيع أي
صورة نظام تشغيل Android تم إصدارها أو نشرها علنًا باستخدام مجموعة خاصة من
مفاتيح الإصدار التي يمكنك وحدك الوصول إليها.
لإنشاء مجموعة فريدة من مفاتيح الإصدار، شغِّل هذه الأوامر من جذر شجرة Android:
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media networkstack; do \ ./development/tools/make_key ~/.android-certs/$x "$subject"; \ done
يجب تغيير $subject
لتعكس معلومات مؤسستك. يمكنك استخدام أي دليل، ولكن احرص على اختيار
موقع احتياطي وآمن. يختار بعض المورّدين تشفير
مفتاحهم الخاص باستخدام عبارة مرور قوية وتخزين المفتاح المشفَّر
في نظام التحكّم في المصدر، بينما يخزّن آخرون مفاتيح الإصدار في مكان آخر تمامًا،
مثل جهاز كمبيوتر مُفصَل عن الإنترنت.
لإنشاء صورة إصدار، استخدِم:
make dist
sign_target_files_apks \ -o \ # explained in the next section --default_key_mappings ~/.android-certs out/dist/*-target_files-*.zip \ signed-target_files.zip
يأخذ نص sign_target_files_apks
البرمجي ملفات مستهدَفة
.zip
كمدخل وينشئ ملفات مستهدَفة جديدة .zip
تم فيها توقيع جميع ملفات .apk
باستخدام مفاتيح جديدة. يمكنك العثور على الصور التي تم توقيعها حديثًا ضمن IMAGES/
في
signed-target_files.zip
.
توقيع حزم التحديث عبر الهواء
يمكن تحويل ملف zip موقَّع للملفات المستهدفة إلى ملف zip موقَّع للتحديث عبر اتصال لاسلكي باستخدام الإجراء التالي:
ota_from_target_files \
-k (--package_key)
signed-target_files.zip \
signed-ota_update.zip
التوقيعات وتحميل التطبيقات من مصدر غير معروف
لا يؤدي التثبيت من خلال "التثبيت من مصدر غير معروف" إلى تجاوز آلية التحقّق العادية من توقيع الحزمة في وضع الاسترداد. قبل تثبيت حزمة، سيتحقّق وضع الاسترداد من أنّه تم توقيعها باستخدام أحد المفاتيح الخاصة التي تتطابق مع المفاتيح العامة المخزّنة في قسم الاسترداد، تمامًا كما يحدث مع الحزمة التي يتم تسليمها عبر شبكة الجوّال.
يتم عادةً التحقّق من حِزم التحديثات التي يتم استلامها من النظام الرئيسي مرّتين:
مرّة من قِبل النظام الرئيسي باستخدام RecoverySystem.verifyPackage()
الطريقة في واجهة برمجة تطبيقات Android، ثم مرّة أخرى من قِبل
recovery. تتحقق واجهة برمجة التطبيقات RecoverySystem API من التوقيع مقابل المفاتيح العامة
المخزنة في النظام الرئيسي، في الملف /system/etc/security/otacerts.zip
(تلقائيًا). تفحص عملية الاسترداد التوقيع مقابل المفاتيح العامة المخزَّنة
في قرص ذاكرة الوصول العشوائي في قسم الاسترداد في الملف /res/keys
.
بشكلٍ تلقائي، تضبط الملفات المستهدفة .zip
التي ينشئها الإصدار شهادة OTA لتتطابق مع مفتاح الاختبار. على أي صورة تم إصدارها، يجب استخدام شهادة مختلفة حتى تتمكّن الأجهزة من التحقّق من صحة حزمة التحديث. يؤدي تمرير علامة -o
إلى
sign_target_files_apks
كما هو موضّح في القسم السابق إلى استبدال
شهادة مفتاح الاختبار بشهادة مفتاح الإصدار من دليل الشهادات.
عادةً ما تخزِّن صورة النظام وصورة الاسترداد المجموعة نفسها من مفاتيح OTA العامة. من خلال إضافة مفتاح إلى مجموعة مفاتيح الاسترداد فقط، يمكن توقيع الحِزم التي لا يمكن تثبيتها إلا من خلال التثبيت من مصدر غير معروف (على افتراض أنّ آلية تنزيل التحديثات للنظام الرئيسي تُجري بشكلٍ صحيح عملية التحقّق من ملف otacerts.zip). يمكنك تحديد مفاتيح إضافية ليتم تضمينها في عملية الاسترداد فقط من خلال ضبط المتغيّر PRODUCT_EXTRA_RECOVERY_KEYS في تعريف المنتج:
vendor/yoyodyne/tardis/products/tardis.mk
[...] PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload
ويشمل ذلك المفتاح العام
vendor/yoyodyne/security/tardis/sideload.x509.pem
في ملف مفاتيح
استرجاع البيانات حتى يتمكّن من تثبيت الحِزم الموقَّعة
بواسطته. لا يتم تضمين المفتاح الإضافي في otacerts.zip، لذا
لا تستدعي الأنظمة التي تتحقق بشكل صحيح من الحزم التي تم تنزيلها عملية استرداد
الحزم الموقعة باستخدام هذا المفتاح.
الشهادات والمفاتيح الخاصة
يأتي كل مفتاح في ملفَّين: الشهادة التي تحتوي على الإضافة .x509.pem والمفتاح الخاص الذي يحتوي على الإضافة .pk8. يجب الحفاظ على سرية المفتاح الخاص، وهو مطلوب لتوقيع حزمة. قد يكون المفتاح نفسه محميًا بكلمة مرور. في المقابل، لا تحتوي الشهادة إلا على النصف العام من المفتاح، لذا يمكن توزيعها على نطاق واسع. يُستخدم للتحقق من توقيع الحزمة بواسطة المفتاح الخاص المقابل.
يستخدم الإصدار العادي من Android خمسة مفاتيح، وجميعها متوفّرة في
build/target/product/security
:
- testkey
- مفتاح تلقائي عام للحزم التي لا تحدد مفتاحًا.
- نظام
- مفتاح اختبار للحِزم التي تشكّل جزءًا من المنصة الأساسية:
- تمت المشاركة
- مفتاح اختبار للعناصر التي تتم مشاركتها في عملية المنزل/جهات الاتصال
- وسائط
- اختبار المفتاح للحزم التي تشكل جزءًا من نظام الوسائط/التنزيل
تحدد الحزم الفردية أحد هذه المفاتيح عن طريق تعيين LOCAL_CERTIFICATE في ملف Android.mk. (يُستخدَم مفتاح الاختبار في حال عدم ضبط هذا المتغيّر). يمكنك أيضًا تحديد مفتاح مختلف تمامًا حسب اسم المسار، على سبيل المثال:
device/yoyodyne/apps/SpecialApp/Android.mk
[...] LOCAL_CERTIFICATE := device/yoyodyne/security/special
يستخدم الإصدار الآن مفتاح device/yoyodyne/security/special.{x509.pem,pk8}
لتوقيع SpecialApp.apk. لا يمكن للإصدار استخدام سوى المفاتيح الخاصة التي
لم يتم حمايتها بكلمة مرور.
خيارات التوقيع المتقدمة
استبدال مفتاح توقيع حزمة APK
يعمل نص التوقيع sign_target_files_apks
على الملفات
المستهدفة التي تم إنشاؤها لإصدار معيّن. يتم تضمين جميع المعلومات عن الشهادات والمفاتيح الخاصة
المستخدَمة في وقت الإنشاء في الملفات المستهدَفة. عند تشغيل النص البرمجي
لتوقيع الإصدار، يمكن استبدال مفاتيح التوقيع استنادًا إلى اسم
المفتاح أو اسم حزمة APK.
استخدِم العلامتَين--key_mapping
و--default_key_mappings
لتحديد استبدال المفتاح استنادًا إلى أسماء المفاتيح:
- يحدِّد الرمز
--key_mapping src_key=dest_key
استبدال مفتاح واحد في كل مرة. - تحدِّد العلامة
--default_key_mappings dir
directory يحتوي على خمسة مفاتيح لاستبدال جميع المفاتيح فيbuild/target/product/security
، وهو ما يعادل استخدام--key_mapping
خمس مرات لتحديد عمليات الربط.
build/target/product/security/testkey = dir/releasekey build/target/product/security/platform = dir/platform build/target/product/security/shared = dir/shared build/target/product/security/media = dir/media build/target/product/security/networkstack = dir/networkstack
استخدِم العلامة
--extra_apks apk_name1,apk_name2,...=key
لتحديد بدائل مفاتيح التوقيع استنادًا إلى أسماء حِزم APK. إذا تم ترك الحقل
key
فارغًا، سيتعامل النص البرمجي مع حِزم APK المحدّدة
على أنّها موقَّعة مسبقًا.
بالنسبة إلى المنتج الافتراضي tardis، ستحتاج إلى ستة مفاتيح محمية بكلمة مرور:
خمسة مفاتيح لاستبدال المفاتيح الخمسة في build/target/product/security
ومفتاح واحد
لاستبدال المفتاح الإضافي device/yoyodyne/security/special
الذي يتطلبه SpecialApp في المثال أعلاه. إذا كانت المفاتيح في
الملفات التالية:
vendor/yoyodyne/security/tardis/releasekey.x509.pem vendor/yoyodyne/security/tardis/releasekey.pk8 vendor/yoyodyne/security/tardis/platform.x509.pem vendor/yoyodyne/security/tardis/platform.pk8 vendor/yoyodyne/security/tardis/shared.x509.pem vendor/yoyodyne/security/tardis/shared.pk8 vendor/yoyodyne/security/tardis/media.x509.pem vendor/yoyodyne/security/tardis/media.pk8 vendor/yoyodyne/security/tardis/networkstack.x509.pem vendor/yoyodyne/security/tardis/networkstack.pk8 vendor/yoyodyne/security/special.x509.pem vendor/yoyodyne/security/special.pk8 # NOT password protected vendor/yoyodyne/security/special-release.x509.pem vendor/yoyodyne/security/special-release.pk8 # password protected
بعد ذلك، عليك توقيع جميع التطبيقات على النحو التالي:
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--key_mapping vendor/yoyodyne/security/special=vendor/yoyodyne/security/special-release \
--extra_apks PresignedApp= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
ويُظهر ذلك ما يلي:
Enter password for vendor/yoyodyne/security/special-release key> Enter password for vendor/yoyodyne/security/tardis/networkstack key> Enter password for vendor/yoyodyne/security/tardis/media key> Enter password for vendor/yoyodyne/security/tardis/platform key> Enter password for vendor/yoyodyne/security/tardis/releasekey key> Enter password for vendor/yoyodyne/security/tardis/shared key> signing: Phone.apk (vendor/yoyodyne/security/tardis/platform) signing: Camera.apk (vendor/yoyodyne/security/tardis/media) signing: NetworkStack.apk (vendor/yoyodyne/security/tardis/networkstack) signing: Special.apk (vendor/yoyodyne/security/special-release) signing: Email.apk (vendor/yoyodyne/security/tardis/releasekey) [...] signing: ContactsProvider.apk (vendor/yoyodyne/security/tardis/shared) signing: Launcher.apk (vendor/yoyodyne/security/tardis/shared) NOT signing: PresignedApp.apk (skipped due to special cert string) rewriting SYSTEM/build.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys signing: framework-res.apk (vendor/yoyodyne/security/tardis/platform) rewriting RECOVERY/RAMDISK/default.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys using: vendor/yoyodyne/security/tardis/releasekey.x509.pem for OTA package verification done.
بعد مطالبة المستخدم بكلمات المرور لجميع المفاتيح المحمية بكلمة مرور، يعيد
النص البرمجي توقيع جميع ملفات APK في هدف الإدخال .zip
باستخدام
مفاتيح الإصدار. قبل تشغيل الأمر، يمكنك أيضًا ضبط
متغيّر بيئة ANDROID_PW_FILE
على اسم ملف مؤقّت، ثم يستدعي النص البرمجي المحرّر للسماح لك بإدخال كلمات المرور لجميع المفاتيح (قد تكون هذه طريقة أكثر ملاءمة لإدخال كلمات المرور).
استبدال مفتاح توقيع APEX
يقدّم Android 10 تنسيق ملف APEX لتثبيت وحدات النظام ذات المستوى الأدنى. كما هو موضّح في توقيع APEX، يتم توقيع كل ملف APEX باستخدام مفتاحين: أحدهما لصورة نظام الملفات المصغَّرة داخل ملف APEX والآخر لملف APEX بالكامل.
عند التوقيع على الإصدار، يتم استبدال مفتاحَي التوقيع لملف APEX بمفاتيح الإصدار. يتم تحديد مفتاح الحمولة لنظام الملفات باستخدام العلامة
--extra_apex_payload
ويتم تحديد مفتاح توقيع ملف APEX بالكامل
باستخدام العلامة --extra_apks
.
بالنسبة إلى منتج tardis، لنفترض أنّ لديك إعدادات المفاتيح التالية
لملفات APEX com.android.conscrypt.apex
وcom.android.media.apex
وcom.android.runtime.release.apex
.
name="com.android.conscrypt.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.media.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.runtime.release.apex" public_key="vendor/yoyodyne/security/testkeys/com.android.runtime.avbpubkey" private_key="vendor/yoyodyne/security/testkeys/com.android.runtime.pem" container_certificate="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.x509.pem" container_private_key="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.pk8"
ولديك الملفات التالية التي تحتوي على مفاتيح الإصدار:
vendor/yoyodyne/security/runtime_apex_container.x509.pem vendor/yoyodyne/security/runtime_apex_container.pk8 vendor/yoyodyne/security/runtime_apex_payload.pem
يلغِي الأمر التالي مفاتيح التوقيع الخاصة بملفَي APK
com.android.runtime.release.apex
و
com.android.tzdata.apex
أثناء توقيع الإصدار. على وجه الخصوص، يتم توقيع
com.android.runtime.release.apex
باستخدام مفاتيح الإصدار
المحدّدة (runtime_apex_container
لملف APEX و
runtime_apex_payload
لحمولة صورة الملف).
يتم التعامل مع com.android.tzdata.apex
على أنّه موقَّع مسبقًا. تتم معالجة جميع ملفات APEX
الأخرى من خلال الإعداد التلقائي كما هو مُدرَج في الملفات المستهدَفة.
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--extra_apks com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_container \
--extra_apex_payload_key com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_payload.pem \
--extra_apks com.android.media.apex= \
--extra_apex_payload_key com.android.media.apex= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
يؤدي تنفيذ الأمر أعلاه إلى عرض السجلات التالية:
[...] signing: com.android.runtime.release.apex container (vendor/yoyodyne/security/runtime_apex_container) : com.android.runtime.release.apex payload (vendor/yoyodyne/security/runtime_apex_payload.pem) NOT signing: com.android.conscrypt.apex (skipped due to special cert string) NOT signing: com.android.media.apex (skipped due to special cert string) [...]
خيارات أخرى
يعيد نص التوقيع sign_target_files_apks
كتابة وصف الإصدار
ومعرفه في ملفات سمات الإصدار للإشارة إلى أنّ الإصدار
موقَّع. تتحكّم العلامة --tag_changes
في التعديلات التي تتم على الملف المرجعي. يمكنك تشغيل النص البرمجي باستخدام -h
للاطّلاع على مستندات عن جميع الإشارات.
إنشاء مفاتيح يدويًا
يستخدم نظام التشغيل Android مفاتيح RSA بسعة 2048 بت مع الأس العام 3. يمكنك إنشاء أزواج مفاتيح التشفير/الشهادات باستخدام أداة openssl من openssl.org:
# generate RSA keyopenssl genrsa -3 -out temp.pem 2048
Generating RSA private key, 2048 bit long modulus ....+++ .....................+++ e is 3 (0x3) # create a certificate with the public part of the keyopenssl req -new -x509 -key temp.pem -out releasekey.x509.pem -days 10000 -subj '/C=US/ST=California/L=San Narciso/O=Yoyodyne, Inc./OU=Yoyodyne Mobility/CN=Yoyodyne/emailAddress=yoyodyne@example.com'
# create a PKCS#8-formatted version of the private keyopenssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt
# securely delete the temp.pem fileshred --remove temp.pem
ينشئ الأمر opensl pkcs8 الموضح أعلاه ملف .pk8 مع no
كلمة مرور، ويكون مناسبًا للاستخدام مع نظام التصميم. لإنشاء ملف pk8 .مشفَّر
بكلمة مرور (يجب إجراء ذلك لجميع مفاتيح الإصدار الفعلية)، استبدِل وسيطة
-nocrypt
ب-passout stdin
، ثم سيشفِّر openssl
المفتاح الخاص باستخدام كلمة مرور يتم قراءتها من الإدخال العادي. لا تتم طباعة أي
طلب، لذا إذا كان stdin هو المحطة الطرفية، سيبدو أنّ البرنامج قد توقّف عن العمل
بينما يكون في الواقع في انتظارك لإدخال كلمة مرور. يمكن استخدام القيم الأخرى
في وسيطة المرور لقراءة كلمة المرور من مواقع أخرى.
لمعرفة التفاصيل، يُرجى الاطّلاع على
وثائق openssl.
يحتوي ملف temp.pem المتوسط على المفتاح الخاص بدون أي نوع من الحماية بكلمة مرور، لذا يجب التخلص منه بعناية عند إنشاء مفاتيح الإصدار. وعلى وجه التحديد، قد لا تكون الأداة GNUshred فعّالة على أنظمة الملفات التي تُسجِّل العمليات على الشبكة أو التي تُسجِّل العمليات على الشبكة. يمكنك استخدام دليل عمل على قرص RAM (مثل قسم tmpfs) عند إنشاء المفاتيح لضمان عدم تعريض مفاتيح التشفير الوسيطة عن غير قصد.
إنشاء ملفات صور
عند توفُّر signed-target_files.zip
، عليك
إنشاء الصورة حتى تتمكّن من وضعها على جهاز.
لإنشاء الصورة الموقَّعة من الملفات المستهدَفة، نفِّذ
الأمر التالي من جذر شجرة Android:
img_from_target_files signed-target_files.zip signed-img.zipيحتوي الملف
signed-img.zip
على جميع ملفات .img
.
لتحميل صورة على جهاز، استخدِم Fastboot على النحو التالي:
fastboot update signed-img.zip