تستخدم صور نظام التشغيل Android التوقيعات المشفرة في مكانين:
- يجب توقيع كل ملف
.apk
داخل الصورة. يستخدم مدير الحزم في Android توقيع.apk
بطريقتين:- عند استبدال أحد التطبيقات ، يجب توقيعه بنفس مفتاح التطبيق القديم من أجل الوصول إلى بيانات التطبيق القديم. هذا صحيح بالنسبة لتحديث تطبيقات المستخدم عن طريق الكتابة فوق
.apk
، ولتجاوز تطبيق النظام بإصدار أحدث مثبت ضمن/data
. - إذا رغب تطبيقان أو أكثر في مشاركة معرف مستخدم (حتى يتمكنوا من مشاركة البيانات ، وما إلى ذلك) ، فيجب توقيعهم باستخدام نفس المفتاح.
- عند استبدال أحد التطبيقات ، يجب توقيعه بنفس مفتاح التطبيق القديم من أجل الوصول إلى بيانات التطبيق القديم. هذا صحيح بالنسبة لتحديث تطبيقات المستخدم عن طريق الكتابة فوق
- يجب توقيع حزم تحديث 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/
in signed-target_files.zip
.
توقيع حزم OTA
يمكن تحويل ملف مضغوط موقع عليه إلى ملف مضغوط لتحديث OTA باستخدام الإجراء التالي:
ota_from_target_files \
-k (--package_key)
signed-target_files.zip \
signed-ota_update.zip
التوقيعات والتحميل الجانبي
لا يتجاوز التحميل الجانبي آلية التحقق من توقيع الحزمة العادية - قبل تثبيت الحزمة ، سيتحقق الاسترداد من توقيعها بأحد المفاتيح الخاصة التي تطابق المفاتيح العامة المخزنة في قسم الاسترداد ، تمامًا كما يحدث مع الحزمة التي يتم تسليمها عبر -هواء.
عادةً ما يتم التحقق من حزم التحديث الواردة من النظام الرئيسي مرتين: مرة بواسطة النظام الرئيسي ، باستخدام طريقة RecoverySystem.verifyPackage()
في واجهة برمجة تطبيقات android ، ثم مرة أخرى عن طريق الاسترداد. يتحقق 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. (يتم استخدام 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 ، افترض أن لديك تكوين المفتاح التالي لملفات 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 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
يقوم الأمر openssl pkcs8 الوارد أعلاه بإنشاء ملف .pk8 بدون كلمة مرور ، وهو مناسب للاستخدام مع نظام الإنشاء. لإنشاء ملف .pk8 مؤمن بكلمة مرور (وهو ما يجب عليك فعله لجميع مفاتيح الإصدار الفعلية) ، استبدل الوسيطة -nocrypt
بـ -passout stdin
؛ ثم يقوم openssl بتشفير المفتاح الخاص بكلمة مرور مقروءة من الإدخال القياسي. لا تتم طباعة أي مطالبة ، لذلك إذا كان stdin هو الجهاز الطرفي ، فسيظهر البرنامج متوقفًا عندما ينتظر حقًا إدخال كلمة مرور. يمكن استخدام القيم الأخرى للوسيطة-passout لقراءة كلمة المرور من مواقع أخرى ؛ لمزيد من التفاصيل ، راجع وثائق openssl .
يحتوي الملف الوسيط temp.pem على المفتاح الخاص بدون أي نوع من الحماية بكلمة مرور ، لذا تخلص منه بعناية عند إنشاء مفاتيح التحرير. على وجه الخصوص ، قد لا تكون الأداة المساعدة GNUshred فعالة على الشبكة أو أنظمة الملفات المسجلة في دفتر اليومية. يمكنك استخدام دليل عمل موجود في قرص RAM (مثل قسم tmpfs) عند إنشاء مفاتيح للتأكد من عدم تعرض الوسائط الوسيطة عن غير قصد.
إنشاء ملفات الصور
بمجرد التوقيع على ملف -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