توقيع النُسخ التجريبية للإصدار

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

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

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

يتضمّن هيكل 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.

توقيع حِزم OTA

يمكن تحويل ملف ‎.zip للملفات المستهدَفة الموقَّع إلى ملف ‎.zip لتحديث OTA موقَّع باستخدام الإجراء التالي:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

التواقيع والتحميل الجانبي

لا يتجاوز التحميل الجانبي آلية التحقّق العادية من توقيع الحزمة في وضع الاسترداد. قبل تثبيت حزمة، سيتحقّق وضع الاسترداد من توقيعها باستخدام أحد المفاتيح الخاصة المطابقة للمفاتيح العامة المخزّنة في قسم الاسترداد، تمامًا كما يفعل مع حزمة يتم تسليمها عبر الهواء.

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

تحدّد الحِزم الفردية أحد هذه المفاتيح من خلال ضبط LOCAL_CERTIFICATE في ملف Android.mk. (يتم استخدام testkey إذا لم يتم ضبط هذا المتغيّر). يمكنك أيضًا تحديد مفتاح مختلف تمامًا حسب اسم المسار، على سبيل المثال:

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 دليلاً يحتوي على خمسة مفاتيح لاستبدال جميع المفاتيح في 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

يستبدل الأمر التالي مفاتيح التوقيع لـ 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

ينشئ أمر openssl pkcs8 أعلاه ملف ‎ .pk8 بدون كلمة مرور، وهو مناسب للاستخدام مع نظام الإنشاء. لإنشاء ملف ‎.pk8 محمي بكلمة مرور (يجب إجراء ذلك لجميع مفاتيح الإصدار الفعلية)، استبدِل الوسيطة -nocrypt بالوسيطة -passout stdin. بعد ذلك، سيشفّر openssl المفتاح الخاص بكلمة مرور تتم قراءتها من الإدخال العادي. لا يتم عرض أي طلب، لذا إذا كان الإدخال العادي هو المحطة الطرفية، سيبدو البرنامج معلّقًا بينما ينتظر منك إدخال كلمة مرور. يمكن استخدام قيم أخرى للوسيطة -passout لقراءة كلمة المرور من مواقع أخرى. للحصول على التفاصيل، اطّلِع على مستندات 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