Menandatangani build untuk rilis

Android OS image menggunakan tanda tangan kriptografi di dua tempat:

  1. Setiap file .apk di dalam gambar harus ditandatangani. milik Android Pengelola Paket menggunakan tanda tangan .apk dengan dua cara:
    • Bila diganti, aplikasi harus ditandatangani dengan kunci yang sama dengan aplikasi lama untuk mendapatkan akses ke data aplikasi lama. Ini memegang benar (true) untuk mengupdate aplikasi pengguna dengan menimpa .apk, mengganti aplikasi sistem dengan versi yang lebih baru yang diinstal di /data.
    • Jika dua aplikasi atau lebih ingin berbagi ID pengguna (sehingga mereka dapat berbagi data, dll.), mereka harus ditandatangani dengan kunci yang sama.
  2. Paket pembaruan OTA harus ditandatangani dengan salah satu kunci yang diharapkan oleh sistem atau proses instalasi akan menolaknya.

Lepaskan

Hierarki Android menyertakan test-keys pada build/target/product/security. Membuat Android OS image menggunakan make akan menandatangani semua file .apk menggunakan kunci pengujian. Karena kunci pengujian diketahui secara publik, siapa pun dapat menandatanganinya sendiri File .apk dengan kunci yang sama, yang dapat memungkinkannya mengganti atau membajak sistem aplikasi yang dibangun ke dalam OS image Anda. Oleh karena itu, sangat penting untuk menandatangani Android OS image yang dirilis atau di-deploy secara publik dengan serangkaian release-keys yang hanya dapat diakses oleh Anda.

Untuk membuat kumpulan kunci rilis unik Anda sendiri, jalankan perintah ini dari {i>root tree<i} Android Anda:

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 harus diubah untuk mencerminkan gaya tidak akurat atau tidak sesuai. Anda dapat menggunakan direktori mana pun, tetapi berhati-hatilah dalam memilih yang dicadangkan dan aman. Beberapa vendor memilih untuk mengenkripsi kunci pribadi dengan frasa sandi yang kuat dan menyimpan kunci yang terenkripsi dalam kontrol sumber; ada juga yang menyimpan kunci rilis di tempat lain yang sama sekali berbeda, seperti pada komputer dengan air gap.

Untuk membuat image rilis, gunakan:

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

Skrip sign_target_files_apks mengambil file target .zip sebagai input dan menghasilkan file target baru .zip di di mana semua file .apk telah ditandatangani dengan kunci baru. Fitur baru gambar yang ditandatangani dapat ditemukan di bawah IMAGES/ di signed-target_files.zip.

Menandatangani paket OTA

ZIP file target yang ditandatangani dapat dikonversi menjadi zip update OTA yang ditandatangani menggunakan prosedur berikut:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

Tanda tangan dan sideload

Sideload tidak mengabaikan tanda tangan paket normal pemulihan mekanisme verifikasi—sebelum menginstal paket, pemulihan akan memverifikasi bahwa itu ditandatangani dengan salah satu kunci pribadi yang cocok dengan kunci publik yang disimpan di partisi pemulihan, seperti halnya paket yang dikirim melalui udara.

Paket update yang diterima dari sistem utama biasanya diverifikasi dua kali: sekali oleh sistem utama, menggunakan RecoverySystem.verifyPackage() di API Android, lalu melakukannya lagi dengan pemulihan data. RecoverySystem API memeriksa tanda tangan berdasarkan kunci publik disimpan di sistem utama, dalam file /system/etc/security/otacerts.zip (secara default). Pemulihan memeriksa tanda tangan terhadap kunci publik yang disimpan di disk RAM partisi pemulihan, dalam file /res/keys.

Secara default, file target .zip yang dihasilkan oleh build akan menetapkan sertifikat OTA agar cocok dengan kunci pengujian. Pada image yang dirilis, image sertifikat harus digunakan agar perangkat dapat memverifikasi keasliannya memperbarui paket. Meneruskan flag -o ke sign_target_files_apks, seperti yang ditunjukkan di bagian sebelumnya, menggantikan sertifikat kunci pengujian dengan sertifikat kunci rilis dari sertifikat Anda saat ini.

Biasanya image sistem dan image pemulihan menyimpan set OTA yang sama kunci publik tertentu. Dengan menambahkan kunci ke hanya kumpulan kunci pemulihan, dapat menandatangani paket yang hanya dapat diinstal melalui {i>sideload<i} (dengan asumsi mekanisme download pembaruan sistem utama berjalan dengan benar verifikasi terhadap otacerts.zip). Anda dapat menentukan kunci tambahan untuk hanya disertakan dalam pemulihan dengan menyetel PRODUCT_EXTRA_reparasi_KEYS variabel dalam definisi produk Anda:

vendor/yoyodyne/tardis/products/tardis.mk
 [...]

PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload

Termasuk kunci publik vendor/yoyodyne/security/tardis/sideload.x509.pem dalam pemulihan {i>key <i}file sehingga dapat menginstal paket yang ditandatangani dengannya. Namun, kunci ekstra tidak termasuk dalam otacerts.zip, jadi sistem yang memverifikasi paket yang diunduh dengan benar tidak memanggil pemulihan untuk paket yang ditandatangani dengan kunci ini.

Sertifikat dan kunci pribadi

Setiap kunci memiliki dua file: sertifikat, yang memiliki ekstensi .x509.pem, dan kunci pribadi, yang memiliki ekstensi .pk8. Kunci pribadi harus dirahasiakan dan diperlukan untuk menandatangani paket. Kuncinya itu sendiri dapat dilindungi oleh {i>password<i}. Sertifikat, di kontras, hanya berisi setengah publik dari kunci, sehingga dapat didistribusikan secara luas. Ini digunakan untuk memverifikasi bahwa paket telah ditandatangani oleh kunci pribadi.

Build Android standar menggunakan lima kunci, yang semuanya berada di build/target/product/security:

kunci pengujian
Kunci default umum untuk paket yang tidak menentukan kunci.
peron
Uji kunci untuk paket yang merupakan bagian dari platform inti.
berbagi
Uji kunci untuk hal-hal yang dibagikan dalam proses rumah/kontak.
media
Uji kunci untuk paket yang merupakan bagian dari sistem media/download.
networkstack
Uji kunci untuk paket yang merupakan bagian dari sistem jaringan. Tujuan kunci networkstack digunakan untuk menandatangani biner yang dirancang sebagai Komponen Sistem Modular . Jika update modul Anda dibuat secara terpisah dan terintegrasi sebagai bawaan pada image perangkat, Anda mungkin tidak perlu membuat kunci networkstack Hierarki sumber Android.

Setiap paket menentukan salah satu kunci dengan menetapkan LOCAL_CERTIFICATE dalam file Android.mk mereka. (testkey digunakan jika variabel ini tidak ditetapkan.) Anda juga dapat menentukan kunci yang sama sekali berbeda dengan pathname, mis.:

device/yoyodyne/apps/SpecialApp/Android.mk
 [...]

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Sekarang build menggunakan kunci device/yoyodyne/security/special.{x509.pem,pk8} untuk menandatangani SpecialApp.apk. Build hanya dapat menggunakan kunci pribadi yang tidak dilindungi dengan sandi.

Opsi penandatanganan lanjutan

Penggantian kunci penandatanganan APK

Skrip penandatanganan sign_target_files_apks berfungsi pada target file yang dibuat untuk sebuah build. Semua informasi tentang sertifikat dan kunci yang digunakan pada waktu build disertakan dalam file target. Saat menjalankan skrip penandatanganan untuk ditandatangani untuk rilis, kunci penandatanganan dapat diganti berdasarkan kunci nama atau nama APK.

Menggunakan --key_mapping dan --default_key_mappings flag untuk menentukan penggantian kunci berdasarkan nama kunci:

  • Flag --key_mapping src_key=dest_key menentukan penggantian untuk satu kunci pada satu waktu.
  • Flag --default_key_mappings dir menentukan direktori dengan lima kunci untuk mengganti semua kunci di build/target/product/security; itu sama dengan menggunakan --key_mapping lima kali untuk menentukan pemetaan.
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

Gunakan --extra_apks apk_name1,apk_name2,...=key tanda untuk menentukan penggantian kunci penandatanganan berdasarkan nama APK. Jika key dibiarkan kosong, skrip akan memperlakukan APK yang ditentukan telah ditandatangani.

Untuk fiktif produk tardis, Anda memerlukan enam kunci yang dilindungi sandi: lima untuk menggantikan lima di build/target/product/security, dan satu untuk mengganti kunci tambahan device/yoyodyne/security/special yang diperlukan oleh SpecialApp dalam contoh di atas. Jika kuncinya berada di file:

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

Kemudian Anda akan menandatangani semua aplikasi seperti ini:

./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

Hal ini memunculkan hal berikut:

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.

Setelah meminta {i>password<i} kepada pengguna untuk semua kunci yang dilindungi {i>password<i}, menandatangani ulang semua file APK dalam .zip target input dengan tombol rilis. Sebelum menjalankan perintah, Anda juga dapat mengatur Variabel lingkungan ANDROID_PW_FILE menjadi nama file sementara; tindakan skrip kemudian memanggil editor Anda agar Anda bisa memasukkan sandi untuk semua kunci (ini mungkin menjadi cara yang lebih nyaman untuk memasukkan sandi).

Penggantian kunci penandatanganan APEX

Android 10 memperkenalkan Format file APEX untuk menginstal modul sistem tingkat yang lebih rendah. Seperti yang dijelaskan dalam penandatanganan APEX, setiap file APEX ditandatangani dengan dua kunci: satu untuk {i> mini<i} {i>file<i} sistem file dalam APEX dan lainnya untuk seluruh APEX.

Saat menandatangani untuk rilis, kedua kunci penandatanganan untuk file APEX diganti dengan tombol rilis. Kunci payload sistem file ditetapkan dengan atribut flag --extra_apex_payload dan seluruh kunci penandatanganan file APEX yang ditentukan dengan flag --extra_apks.

Untuk produk tardis, anggap bahwa Anda memiliki konfigurasi kunci berikut untuk com.android.conscrypt.apex, com.android.media.apex dan com.android.runtime.release.apex file 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"

Dan Anda memiliki file berikut yang berisi kunci rilis:

vendor/yoyodyne/security/runtime_apex_container.x509.pem
vendor/yoyodyne/security/runtime_apex_container.pk8
vendor/yoyodyne/security/runtime_apex_payload.pem

Perintah berikut mengganti kunci penandatanganan untuk com.android.runtime.release.apex dan com.android.tzdata.apex selama penandatanganan rilis. Secara khusus, kita akan membuat com.android.runtime.release.apex ditandatangani dengan kunci rilis (runtime_apex_container untuk file APEX, dan runtime_apex_payload untuk payload image file). com.android.tzdata.apex diperlakukan sebagai telah ditandatangani sebelumnya. Semua APEX lainnya file ditangani oleh konfigurasi {i>default<i} seperti yang tercantum dalam file target.

./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

Menjalankan perintah di atas akan memberikan log berikut:

        [...]
    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)
        [...]

Opsi lainnya

Skrip penandatanganan sign_target_files_apks menulis ulang build deskripsi dan sidik jari dalam file properti build untuk menunjukkan bahwa adalah build bertanda tangan. Tanda --tag_changes mengontrol hasil edit yang dibuat pada sidik jari. Jalankan skrip dengan -h untuk melihat dokumentasi tentang semua tanda.

Buat kunci secara manual

Android menggunakan kunci RSA 2048-bit dengan eksponen publik 3. Anda dapat membuat pasangan sertifikat/kunci pribadi menggunakan alat openssl dari 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

Perintah openssl pkcs8 yang diberikan di atas membuat file .pk8, dengan no {i>password<i}, yang cocok untuk digunakan dengan sistem build. Untuk membuat .pk8 yang aman dengan sandi (yang harus Anda lakukan untuk semua kunci rilis yang sebenarnya), ganti Argumen -nocrypt dengan -passout stdin; lalu openssl akan mengenkripsi kunci pribadi dengan {i> password<i} yang dibaca dari input standar. Lain kali akan dicetak, jadi jika {i>stdin<i} adalah terminalnya, program akan tampak hang ketika benar-benar hanya menunggu Anda memasukkan {i>password<i}. Nilai lainnya dapat berupa digunakan untuk argumen {i>-passout<i} untuk membaca {i>password<i} dari lokasi lain; untuk selengkapnya, lihat dokumentasi openssl.

File perantara temp.pem berisi kunci pribadi tanpa segala jenis perlindungan sandi, jadi buanglah dengan bijak saat membuat rilis tombol. Secara khusus, utilitas GNUshred mungkin tidak efektif pada jaringan atau sistem file jurnal. Anda dapat menggunakan direktori kerja yang terletak di {i>disk<i} RAM (seperti partisi tmpfs) saat membuat kunci untuk memastikan perantara tidak terekspos secara tidak sengaja.

Membuat file gambar

Jika memiliki signed-target_files.zip, Anda harus membuat {i>image<i} sehingga Anda dapat memasukkannya ke dalam perangkat. Untuk membuat gambar bertanda tangan dari file target, jalankan perintah berikut dari root Android hierarki:

img_from_target_files signed-target_files.zip signed-img.zip
File yang dihasilkan, signed-img.zip, berisi semua file .img. Untuk memuat gambar ke perangkat, gunakan fastboot sebagai berikut ini:
fastboot update signed-img.zip