علامة يبني من أجل الإفراج

تستخدم صور نظام التشغيل 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

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

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

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

عادةً ما يتم التحقق من حزم التحديثات المستلمة من النظام الرئيسي مرتين: مرة واحدة بواسطة النظام الرئيسي، باستخدام طريقة RecoverySystem.verifyPackage() في android API، ثم مرة أخرى عن طريق الاسترداد. تتحقق واجهة برمجة تطبيقات RecoverySystem من التوقيع مقابل المفاتيح العامة المخزنة في النظام الرئيسي، في الملف /system/etc/security/otacerts.zip (افتراضيًا). يتحقق الاسترداد من التوقيع مقابل المفاتيح العامة المخزنة في قرص ذاكرة الوصول العشوائي (RAM) لقسم الاسترداد، في الملف /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 :

مفتاح الاختبار
المفتاح الافتراضي العام للحزم التي لا تحدد مفتاحًا.
منصة
مفتاح الاختبار للحزم التي تشكل جزءًا من النظام الأساسي الأساسي.
مشترك
مفتاح اختبار للأشياء التي تتم مشاركتها في عملية المنزل/جهات الاتصال.
وسائط
مفتاح اختبار للحزم التي تشكل جزءًا من نظام الوسائط/التنزيل.
com.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 دليلاً بخمسة مفاتيح لاستبدال جميع المفاتيح في 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، افترض أن لديك تكوين المفتاح التالي لملفات com.android.conscrypt.apex و com.android.media.apex و com.android.runtime.release.apex ملفات 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 ؛ ثم سيقوم opensl بتشفير المفتاح الخاص بكلمة مرور مقروءة من الإدخال القياسي. لا تتم طباعة أي مطالبة، لذا إذا كان stdin هو الطرفية، فسيبدو البرنامج معلقًا عندما يكون في انتظار إدخال كلمة المرور. يمكن استخدام قيم أخرى للوسيطة-passout لقراءة كلمة المرور من مواقع أخرى؛ لمزيد من التفاصيل، راجع وثائق opensl .

يحتوي الملف الوسيط 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