لافتات تصدر للإصدارات

تستخدِم صور نظام التشغيل Android توقيعات مشفَّرة في مكانَين:

  1. يجب أن يكون كل ملف .apk داخل الصورة موقَّعًا. يستخدم مدير حزم Android توقيع .apk بطريقتَين:
    • عند استبدال تطبيق ما، يجب توقيعه باستخدام المفتاح نفسه المُستخدَم في التطبيق القديم من أجل الوصول إلى بيانات التطبيق القديم. وينطبق ذلك على حد سواء عند تحديث تطبيقات المستخدمين من خلال استبدال .apk، وعند استبدال تطبيق نظام بإصدار أحدث تم تثبيته ضمن /data.
    • إذا أرادت تطبيقان أو أكثر مشاركة معرّف مستخدم (كي يتمكّنوا من مشاركة data وغيرها)، يجب توقيعهما باستخدام المفتاح نفسه.
  2. يجب توقيع حِزم التحديثات عبر الهواء باستخدام أحد المفاتيح المتوقّعة من النظام، وإلا سترفض عملية التثبيت هذه الحِزم.

مفاتيح الإصدار

تتضمّن شجرة 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
مفتاح تلقائي عام للحزم التي لا تحدد مفتاحًا.
نظام
مفتاح اختبار للحِزم التي تشكّل جزءًا من المنصة الأساسية:
تمت المشاركة
مفتاح اختبار للعناصر التي تتم مشاركتها في عملية المنزل/جهات الاتصال
وسائط
اختبار المفتاح للحزم التي تشكل جزءًا من نظام الوسائط/التنزيل
networkstack
مفتاح اختبار للحِزم التي تشكّل جزءًا من نظام الشبكات يُستخدَم مفتاح networkstack لتوقيع الملفات الثنائية المصمّمة على أنّها مكونات نظام وحدات . إذا تم إنشاء تحديثات الوحدات بشكل منفصل ودمجها كعناصر مضمَّنة مسبقًا في صورة جهازك، قد لا تحتاج إلى إنشاء مفتاح شبكات في شجرة مصادر Android.

تحدد الحزم الفردية أحد هذه المفاتيح عن طريق تعيين 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 key
openssl 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 key
openssl 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 key
openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt

# securely delete the temp.pem file
shred --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