Image OS Android menggunakan tanda tangan kriptografi di dua tempat:
- Setiap file
.apk
di dalam gambar harus ditandatangani. Pengelola Paket Android menggunakan tanda tangan.apk
dalam dua cara:- Saat diganti, aplikasi harus ditandatangani dengan kunci yang sama seperti aplikasi lama agar mendapatkan akses ke data aplikasi lama. Hal ini berlaku
baik untuk mengupdate aplikasi pengguna dengan mengganti
.apk
, maupun untuk mengganti aplikasi sistem dengan versi yang lebih baru yang diinstal di/data
. - Jika dua aplikasi atau lebih ingin berbagi ID pengguna (sehingga dapat berbagi data, dll.), aplikasi tersebut harus ditandatangani dengan kunci yang sama.
- Saat diganti, aplikasi harus ditandatangani dengan kunci yang sama seperti aplikasi lama agar mendapatkan akses ke data aplikasi lama. Hal ini berlaku
baik untuk mengupdate aplikasi pengguna dengan mengganti
- Paket update OTA harus ditandatangani dengan salah satu kunci yang diharapkan oleh sistem atau proses penginstalan akan menolaknya.
Kunci rilis
Struktur Android mencakup test-keys di bagian
build/target/product/security
. Membangun image OS Android
menggunakan make
akan menandatangani semua file .apk
menggunakan
test-keys. Karena kunci pengujian diketahui secara publik, siapa pun dapat menandatangani file .apk mereka sendiri dengan kunci yang sama, yang dapat memungkinkan mereka mengganti atau membajak aplikasi sistem yang di-build ke dalam image OS Anda. Oleh karena itu, sangat penting untuk menandatangani image OS Android yang dirilis atau di-deploy secara publik dengan serangkaian kunci rilis khusus yang hanya dapat diakses oleh Anda.
Untuk membuat kumpulan kunci rilis unik Anda sendiri, jalankan perintah berikut dari root direktori 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 informasi organisasi Anda. Anda dapat menggunakan direktori apa pun, tetapi berhati-hatilah dalam memilih lokasi yang dicadangkan dan aman. Beberapa vendor memilih untuk mengenkripsi kunci pribadinya dengan frasa sandi yang kuat dan menyimpan kunci yang dienkripsi dalam kontrol sumber; vendor lain menyimpan kunci rilisnya di tempat lain, seperti di komputer yang tidak terhubung ke internet.
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 .zip
target-files sebagai input dan menghasilkan .zip
target-files baru yang di dalamnya semua file .apk
telah ditandatangani dengan kunci baru. Gambar yang baru ditandatangani dapat ditemukan di bagian IMAGES/
dalam signed-target_files.zip
.
Menandatangani paket OTA
File zip target yang ditandatangani dapat dikonversi menjadi file 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 memuat dari luar Play Store
Memuat dari samping tidak melewati mekanisme verifikasi tanda tangan paket normal pemulihan—sebelum menginstal paket, pemulihan akan memverifikasi bahwa paket ditandatangani dengan salah satu kunci pribadi yang cocok dengan kunci publik yang disimpan di partisi pemulihan, seperti halnya untuk paket yang dikirimkan melalui jaringan nirkabel.
Paket update yang diterima dari sistem utama biasanya diverifikasi dua kali:
sekali oleh sistem utama, menggunakan metode
RecoverySystem.verifyPackage()
di Android API, dan kemudian diverifikasi lagi oleh
pemulihan. RecoverySystem API memeriksa tanda tangan terhadap kunci publik yang 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, .zip
target-files yang dihasilkan oleh build menetapkan
sertifikat OTA agar cocok dengan kunci pengujian. Pada image yang dirilis, sertifikat yang berbeda harus digunakan agar perangkat dapat memverifikasi keaslian paket update. Meneruskan tanda -o
ke
sign_target_files_apks
, seperti yang ditunjukkan di bagian sebelumnya, akan menggantikan
sertifikat kunci pengujian dengan sertifikat kunci rilis dari direktori
certs Anda.
Biasanya, image sistem dan image pemulihan menyimpan set kunci publik OTA yang sama. Dengan menambahkan kunci ke hanya kumpulan kunci pemulihan, paket yang dapat diinstal hanya melalui sideloading dapat ditandatangani (dengan asumsi mekanisme download update sistem utama melakukan verifikasi dengan benar terhadap otacerts.zip). Anda dapat menentukan kunci tambahan yang akan disertakan hanya dalam pemulihan dengan menyetel variabel PRODUCT_EXTRA_RECOVERY_KEYS dalam definisi produk Anda:
vendor/yoyodyne/tardis/products/tardis.mk
[...] PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload
Hal ini mencakup kunci publik
vendor/yoyodyne/security/tardis/sideload.x509.pem
dalam file kunci pemulihan
sehingga dapat menginstal paket yang ditandatangani
dengannya. Kunci tambahan tidak disertakan dalam otacerts.zip, jadi
sistem yang memverifikasi paket yang didownload dengan benar tidak akan memanggil pemulihan untuk
paket yang ditandatangani dengan kunci ini.
Sertifikat dan kunci pribadi
Setiap kunci tersedia dalam dua file: sertifikat, yang memiliki ekstensi .x509.pem, dan kunci pribadi, yang memiliki ekstensi .pk8. Kunci pribadi harus dirahasiakan dan diperlukan untuk menandatangani paket. Kunci itu sendiri dapat dilindungi dengan sandi. Sebaliknya, sertifikat hanya berisi bagian publik dari kunci, sehingga dapat didistribusikan secara luas. Kunci ini digunakan untuk memverifikasi bahwa paket telah ditandatangani oleh kunci pribadi yang sesuai.
Build Android standar menggunakan lima kunci, yang semuanya berada di
build/target/product/security
:
- testkey
- Kunci default generik untuk paket yang tidak menentukan kunci.
- platform
- Kunci pengujian untuk paket yang merupakan bagian dari platform inti.
- bersama
- Kunci pengujian untuk hal-hal yang dibagikan dalam proses rumah/kontak.
- media
- Kunci pengujian untuk paket yang merupakan bagian dari sistem media/download.
Setiap paket menentukan salah satu kunci ini dengan menetapkan LOCAL_CERTIFICATE dalam file Android.mk-nya. (testkey digunakan jika variabel ini tidak disetel.) Anda juga dapat menentukan kunci yang sama sekali berbeda berdasarkan nama jalur, misalnya:
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 sandi.
Opsi penandatanganan lanjutan
Penggantian kunci penandatanganan APK
Skrip penandatanganan sign_target_files_apks
berfungsi pada file target yang dibuat untuk build. Semua informasi tentang sertifikat dan kunci
pribadi yang digunakan pada waktu build disertakan dalam file target. Saat menjalankan
skrip penandatanganan untuk menandatangani rilis, kunci penandatanganan dapat diganti berdasarkan nama kunci atau nama APK.
Gunakan flag --key_mapping
dan --default_key_mappings
untuk menentukan penggantian kunci berdasarkan nama kunci:
- Flag
--key_mapping src_key=dest_key
menentukan penggantian satu tombol dalam satu waktu. - Flag
--default_key_mappings dir
menentukan direktori dengan lima kunci untuk menggantikan semua kunci dibuild/target/product/security
; ini setara 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 tanda
--extra_apks apk_name1,apk_name2,...=key
untuk menentukan penggantian kunci penandatanganan berdasarkan nama APK. Jika
key
dibiarkan kosong, skrip akan memperlakukan APK yang ditentukan
sebagai APK yang telah ditandatangani sebelumnya.
Untuk produk tardis hipotetis, Anda memerlukan enam kunci yang dilindungi sandi:
lima untuk menggantikan lima kunci di build/target/product/security
, dan satu
untuk menggantikan kunci tambahan device/yoyodyne/security/special
yang diperlukan oleh SpecialApp dalam contoh di atas. Jika kunci berada di file berikut:
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
Tindakan ini akan menampilkan 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 sandi pengguna untuk semua kunci yang dilindungi sandi, skrip akan menandatangani ulang semua file APK di target input .zip
dengan kunci rilis. Sebelum menjalankan perintah, Anda juga dapat menetapkan variabel lingkungan ANDROID_PW_FILE
ke nama file sementara; skrip kemudian memanggil editor untuk memungkinkan Anda memasukkan sandi untuk semua kunci (ini mungkin cara yang lebih mudah untuk memasukkan sandi).
Penggantian kunci penandatanganan APEX
Android 10 memperkenalkan format file APEX untuk menginstal modul sistem tingkat bawah. Seperti yang dijelaskan dalam penandatanganan APEX, setiap file APEX ditandatangani dengan dua kunci: satu untuk image sistem file mini dalam APEX dan satu lagi untuk seluruh APEX.
Saat menandatangani untuk rilis, dua kunci penandatanganan untuk file APEX diganti
dengan kunci rilis. Kunci payload sistem file ditentukan dengan tanda
--extra_apex_payload
dan seluruh kunci penandatanganan file APEX ditentukan
dengan tanda --extra_apks
.
Untuk produk tardis, asumsikan bahwa Anda memiliki konfigurasi kunci berikut untuk file APEX com.android.conscrypt.apex
, com.android.media.apex
, dan 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"
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 menggantikan kunci penandatanganan untuk
com.android.runtime.release.apex
dan
com.android.tzdata.apex
selama penandatanganan rilis. Khususnya, com.android.runtime.release.apex
ditandatangani dengan
kunci rilis yang ditentukan (runtime_apex_container
untuk file APEX, dan
runtime_apex_payload
untuk payload gambar file).
com.android.tzdata.apex
diperlakukan sebagai sudah ditandatangani sebelumnya. Semua file APEX
lainnya ditangani oleh konfigurasi default 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 deskripsi dan sidik jari build dalam file properti build untuk menunjukkan bahwa build adalah build yang ditandatangani. Flag --tag_changes
mengontrol pengeditan yang dilakukan pada sidik jari. Jalankan skrip dengan -h
untuk melihat dokumentasi semua flag.
Membuat kunci secara manual
Android menggunakan kunci RSA 2048-bit dengan eksponen publik 3. Anda dapat membuat pasangan kunci pribadi/sertifikat menggunakan alat openssl dari 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
Perintah openssl pkcs8 yang diberikan di atas akan membuat file .pk8 tanpa
sandi, yang cocok untuk digunakan dengan sistem build. Untuk membuat .pk8 yang diamankan
dengan sandi (yang harus Anda lakukan untuk semua kunci rilis sebenarnya), ganti argumen
-nocrypt
dengan -passout stdin
; lalu openssl
akan mengenkripsi kunci pribadi dengan sandi yang dibaca dari input standar. Tidak ada
prompt yang dicetak, jadi jika stdin adalah terminal, program akan tampak berhenti
padahal sebenarnya hanya menunggu Anda memasukkan sandi. Nilai lain dapat
digunakan untuk argumen -passout guna membaca sandi dari lokasi lain; untuk
detailnya, lihat
dokumentasi openssl.
File perantara temp.pem berisi kunci pribadi tanpa perlindungan sandi apa pun, jadi hapus file tersebut dengan bijak saat membuat kunci rilis. Secara khusus, utilitas GNUshred mungkin tidak efektif pada sistem file jaringan atau yang di-journal. Anda dapat menggunakan direktori kerja yang berada di disk RAM (seperti partisi tmpfs) saat membuat kunci untuk memastikan perantara tidak diekspos secara tidak sengaja.
Membuat file gambar
Jika sudah memiliki signed-target_files.zip
, Anda perlu
membuat gambar agar dapat memasukkannya ke perangkat.
Untuk membuat image bertanda tangan dari file target, jalankan
perintah berikut dari root tree Android:
img_from_target_files signed-target_files.zip signed-img.zip
signed-img.zip
, berisi semua file .img
.
Untuk memuat gambar ke perangkat, gunakan fastboot sebagai berikut:
fastboot update signed-img.zip