تصاویر سیستم عامل اندروید در دو مکان از امضای رمزنگاری استفاده می کنند:
- هر فایل
.apk
داخل تصویر باید امضا شود. Package Manager Android به دو صورت از امضای.apk
. استفاده می کند:- هنگامی که یک برنامه جایگزین می شود، باید با همان کلید برنامه قدیمی امضا شود تا بتوان به داده های برنامه قدیمی دسترسی داشت. این امر هم برای بهروزرسانی برنامههای کاربر با رونویسی
.apk
و هم برای لغو برنامه سیستمی با نسخه جدیدتر نصب شده در/data
صادق است. - اگر دو یا چند برنامه بخواهند شناسه کاربری را به اشتراک بگذارند (تا بتوانند داده ها و غیره را به اشتراک بگذارند)، باید با همان کلید امضا شوند.
- هنگامی که یک برنامه جایگزین می شود، باید با همان کلید برنامه قدیمی امضا شود تا بتوان به داده های برنامه قدیمی دسترسی داشت. این امر هم برای بهروزرسانی برنامههای کاربر با رونویسی
- بسته های به روز رسانی OTA باید با یکی از کلیدهای مورد انتظار سیستم امضا شوند، در غیر این صورت فرآیند نصب آنها را رد می کند.
کلیدهای آزادسازی
درخت اندروید شامل کلیدهای آزمایشی زیر build/target/product/security
. ساختن یک تصویر سیستم عامل Android با استفاده از make
، همه فایلهای .apk
را با استفاده از کلیدهای تست امضا میکند. از آنجایی که کلیدهای آزمایشی به طور عمومی شناخته شده اند، هر کسی می تواند فایل های apk. خود را با کلیدهای یکسان امضا کند، که ممکن است به آنها اجازه دهد برنامه های سیستمی ساخته شده در تصویر سیستم عامل شما را جایگزین یا ربوده کنند. به همین دلیل بسیار مهم است که هر تصویر عمومی منتشر شده یا مستقر در سیستم عامل اندروید را با مجموعه خاصی از کلیدهای انتشار امضا کنید که فقط شما به آنها دسترسی دارید.
برای ایجاد مجموعه منحصر به فرد خود از کلیدهای انتشار، این دستورات را از ریشه درخت اندروید خود اجرا کنید:
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
یک target-files .zip
را به عنوان ورودی می گیرد و یک target-files .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()
در API اندروید، و سپس دوباره با بازیابی. RecoverySystem API امضا را در برابر کلیدهای عمومی ذخیره شده در سیستم اصلی، در فایل /system/etc/security/otacerts.zip
(به طور پیش فرض) بررسی می کند. Recovery امضای کلیدهای عمومی ذخیره شده در دیسک RAM پارتیشن بازیابی را در فایل /res/keys
بررسی می کند.
به طور پیشفرض، فایلهای .zip
تولید شده توسط بیلد، گواهی OTA را مطابق با کلید تست تنظیم میکند. در تصویر منتشر شده، باید از گواهی متفاوتی استفاده شود تا دستگاهها بتوانند صحت بسته بهروزرسانی را تأیید کنند. ارسال پرچم -o
به sign_target_files_apks
، همانطور که در بخش قبل نشان داده شده است، گواهی کلید تست را با گواهی کلید انتشار از دایرکتوری certs جایگزین می کند.
معمولاً تصویر سیستم و تصویر بازیابی مجموعه ای از کلیدهای عمومی 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. کلید خصوصی باید مخفی بماند و برای امضای بسته مورد نیاز است. ممکن است خود کلید با رمز عبور محافظت شود. در مقابل، گواهی تنها حاوی نیمی از کلید عمومی است، بنابراین می توان آن را به طور گسترده توزیع کرد. برای تأیید اینکه یک بسته توسط کلید خصوصی مربوطه امضا شده است استفاده می شود.
ساخت استاندارد اندروید از پنج کلید استفاده می کند که همه آنها در build/target/product/security
قرار دارند:
- کلید تست
- کلید پیش فرض عمومی برای بسته هایی که در غیر این صورت کلیدی را مشخص نمی کنند.
- پلت فرم
- کلید تست برای بسته هایی که بخشی از پلت فرم اصلی هستند.
- به اشتراک گذاشته شده است
- کلید تست برای چیزهایی که در فرآیند خانه/مخاطبین به اشتراک گذاشته شده است.
- رسانه ها
- کلید تست برای بسته هایی که بخشی از سیستم رسانه/دانلود هستند.
بسته های فردی با تنظیم 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
اندروید 10 فرمت فایل APEX را برای نصب ماژول های سطح پایین سیستم معرفی می کند. همانطور که در امضای APEX توضیح داده شد، هر فایل APEX با دو کلید امضا می شود: یکی برای تصویر سیستم فایل کوچک در یک APEX و دیگری برای کل APEX.
هنگام امضای برای انتشار، دو کلید امضا برای یک فایل APEX با کلیدهای انتشار جایگزین می شوند. کلید payload سیستم فایل با پرچم --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
توضیحات ساخت و اثر انگشت را در فایلهای Build Properties بازنویسی میکند تا نشان دهد که بیلد یک ساخت امضا شده است. پرچم --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 ترمینال باشد، برنامه زمانی که واقعاً منتظر است رمز عبور را وارد کنید، به نظر میرسد که هنگ میکند. مقادیر دیگر را می توان برای آرگومان the-passout برای خواندن رمز عبور از مکان های دیگر استفاده کرد. برای جزئیات، به مستندات openssl مراجعه کنید.
فایل میانی temp.pem حاوی کلید خصوصی بدون هیچ گونه حفاظت رمز عبور است، بنابراین هنگام ایجاد کلیدهای انتشار، آن را با دقت دور بریزید. به طور خاص، ابزار GNUshred ممکن است بر روی سیستم های فایل شبکه یا ژورنال موثر نباشد. هنگام تولید کلیدها می توانید از یک دایرکتوری کار واقع در یک دیسک RAM (مانند یک پارتیشن tmpfs) استفاده کنید تا اطمینان حاصل کنید که واسطه ها به طور ناخواسته در معرض نمایش قرار نمی گیرند.
فایل های تصویری ایجاد کنید
هنگامی که signed-target_files.zip
را دارید، باید تصویر را ایجاد کنید تا بتوانید آن را در یک دستگاه قرار دهید. برای ایجاد تصویر امضا شده از فایل های هدف، دستور زیر را از ریشه درخت اندروید اجرا کنید:
img_from_target_files signed-target_files.zip signed-img.zip
signed-img.zip
، حاوی تمام فایلهای .img
. برای بارگذاری یک تصویر بر روی یک دستگاه، از fastboot به صورت زیر استفاده کنید:fastboot update signed-img.zip