Derlemeleri yayınlamak için imzalama

Android OS görüntüleri iki yerde kriptografik imzalar kullanır:

  1. Resmin içindeki her .apk dosyası imzalanmalıdır. Android'in Paket Yöneticisi, .apk imzayı iki şekilde kullanır:
    • Bir uygulama değiştirildiğinde, eski uygulamanın verilerine erişebilmek için eski uygulamayla aynı anahtarla imzalanması gerekir. Bu durum, hem kullanıcı uygulamalarını .apk üzerine yazarak güncelleme hem de /data altına yüklenen daha yeni bir sürümle sistem uygulamasının üzerine yazma için geçerlidir.
    • İki veya daha fazla uygulama, kullanıcı kimliği paylaşmak (böylece veri paylaşmak vb.) istiyorsa aynı anahtarla imzalanmalıdır.
  2. OTA güncelleme paketleri, sistemin beklediği anahtarlardan biriyle imzalanmalıdır. Aksi takdirde, yükleme işlemi bu paketleri reddeder.

Yayın anahtarları

Android ağacı, build/target/product/security altında test-keys'i içerir. build/target/product/security. make kullanarak Android OS görüntüsü oluşturduğunuzda tüm .apk dosyaları test anahtarları kullanılarak imzalanır. Test anahtarları herkes tarafından bilindiğinden, herkes kendi .apk dosyalarını aynı anahtarlarla imzalayabilir. Bu durum, işletim sistemi görüntünüze yerleştirilmiş sistem uygulamalarının değiştirilmesine veya ele geçirilmesine yol açabilir. Bu nedenle, herkese açık olarak yayınlanan veya dağıtılan Android OS görüntülerini yalnızca sizin erişebildiğiniz özel bir yayın anahtarı grubuyla imzalamanız çok önemlidir.

Kendi benzersiz yayın anahtarı grubunuzu oluşturmak için Android ağacınızın kökünden şu komutları çalıştırın:

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, kuruluşunuzun bilgilerini yansıtacak şekilde değiştirilmelidir. Herhangi bir dizini kullanabilirsiniz ancak yedeklenmiş ve güvenli bir konum seçmeye dikkat edin. Bazı sağlayıcılar özel anahtarlarını güçlü bir parola ile şifrelemeyi ve şifrelenmiş anahtarı kaynak kontrolünde saklamayı tercih ederken bazıları da yayın anahtarlarını tamamen başka bir yerde (ör. internet bağlantısı olmayan bir bilgisayarda) saklar.

Sürüm resmi oluşturmak için şunu kullanın:

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 komut dosyası, giriş olarak bir hedef dosyalar .zip alır ve tüm .apk dosyalarının yeni anahtarlarla imzalandığı yeni bir hedef dosyalar .zip oluşturur. Yeni imzalanan resimleri IMAGES/ bölümündeki signed-target_files.zip altında bulabilirsiniz.

OTA paketlerini imzalama

İmzalı bir target-files.zip dosyası, aşağıdaki prosedür kullanılarak imzalı bir OTA güncelleme zip dosyasına dönüştürülebilir:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

İmzalar ve yan yükleme

Yan yükleme, kurtarma işleminin normal paket imzası doğrulama mekanizmasını atlamaz. Kurtarma işlemi, bir paketi yüklemeden önce, kurtarma bölümünde depolanan ortak anahtarlarla eşleşen özel anahtarlardan biriyle imzalandığını doğrular. Bu işlem, kablosuz olarak teslim edilen bir paket için de aynı şekilde yapılır.

Ana sistemden alınan güncelleme paketleri genellikle iki kez doğrulanır: bir kez ana sistem tarafından android API'deki RecoverySystem.verifyPackage() yöntemi kullanılarak, ardından tekrar kurtarma tarafından. RecoverySystem API, imzayı /system/etc/security/otacerts.zip dosyasında (varsayılan olarak) ana sistemde depolanan ortak anahtarlara göre kontrol eder. Kurtarma, imzayı kurtarma bölümü RAM diskinde /res/keys dosyasında depolanan ortak anahtarlara göre kontrol eder.

Varsayılan olarak, derleme tarafından oluşturulan hedef dosyalar .zip, OTA sertifikasını test anahtarıyla eşleşecek şekilde ayarlar. Yayınlanan bir resimde, cihazların güncelleme paketinin gerçekliğini doğrulayabilmesi için farklı bir sertifika kullanılmalıdır. Önceki bölümde gösterildiği gibi -o işaretini sign_target_files_apks'ye iletmek, test anahtarı sertifikasını certs dizininizdeki yayın anahtarı sertifikasıyla değiştirir.

Normalde sistem görüntüsü ve kurtarma görüntüsü aynı OTA genel anahtar grubunu depolar. Yalnızca kurtarma anahtarı grubuna bir anahtar ekleyerek, yalnızca yan yükleme yoluyla yüklenebilen paketleri imzalamak mümkündür (ana sistemin güncelleme indirme mekanizmasının otacerts.zip'e karşı doğrulamayı doğru şekilde yaptığı varsayılır). Ürün tanımınızda PRODUCT_EXTRA_RECOVERY_KEYS değişkenini ayarlayarak yalnızca kurtarmaya dahil edilecek ek anahtarlar belirtebilirsiniz:

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

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

Bu, kurtarma anahtarları dosyasındaki ortak anahtarı içerir. Böylece, bu anahtarla imzalanmış paketler yüklenebilir.vendor/yoyodyne/security/tardis/sideload.x509.pem Ancak ek anahtar otacerts.zip'e dahil edilmez. Bu nedenle, indirilen paketleri doğru şekilde doğrulayan sistemler, bu anahtarla imzalanan paketler için kurtarma işlemini başlatmaz.

Sertifikalar ve özel anahtarlar

Her anahtar iki dosyadan oluşur: .x509.pem uzantılı sertifika ve .pk8 uzantılı özel anahtar. Özel anahtar kimseyle paylaşılmamalıdır ve paket imzalamak için gereklidir. Anahtarın kendisi şifreyle korunuyor olabilir. Sertifika ise yalnızca anahtarın ortak kısmını içerdiğinden geniş bir şekilde dağıtılabilir. Paketin, ilgili özel anahtarla imzalandığını doğrulamak için kullanılır.

Standart Android derlemesinde beş anahtar kullanılır ve bu anahtarların tümü build/target/product/security içinde yer alır:

testkey
Aksi belirtilmedikçe paketler için genel varsayılan anahtar.
platform
Temel platformun parçası olan paketler için test anahtarı.
paylaşılan
Evde/kişiler sürecinde paylaşılan öğeler için test anahtarı.
medya
Medya/indirme sisteminin parçası olan paketler için test anahtarı.
networkstack
Ağ sisteminin parçası olan paketler için test anahtarı. Networkstack anahtarı, Modüler Sistem Bileşenleri olarak tasarlanan ikili dosyaları imzalamak için kullanılır. Modül güncellemeleriniz ayrı ayrı oluşturulup cihaz resminize önceden oluşturulmuş olarak entegre ediliyorsa Android kaynak ağacında networkstack anahtarı oluşturmanız gerekmeyebilir.

Ayrı ayrı paketler, Android.mk dosyalarında LOCAL_CERTIFICATE'ı ayarlayarak bu anahtarlardan birini belirtir. (Bu değişken ayarlanmamışsa testkey kullanılır.) Ayrıca, yol adına göre tamamen farklı bir anahtar da belirtebilirsiniz. Örneğin:

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

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Artık derlemede SpecialApp.apk'yı imzalamak için device/yoyodyne/security/special.{x509.pem,pk8} anahtarı kullanılıyor. Derlemede yalnızca şifreyle korunmayan özel anahtarlar kullanılabilir.

Gelişmiş imzalama seçenekleri

APK imzalama anahtarını değiştirme

İmzalama komut dosyası sign_target_files_apks, derleme için oluşturulan hedef dosyalarda çalışır. Derleme sırasında kullanılan sertifikalar ve özel anahtarlarla ilgili tüm bilgiler hedef dosyalara dahil edilir. Yayın için imzalama komut dosyası çalıştırılırken imzalama anahtarları, anahtar adına veya APK adına göre değiştirilebilir.

Anahtar adlarına göre anahtar değiştirme işlemini belirtmek için --key_mapping ve --default_key_mappings işaretlerini kullanın:

  • --key_mapping src_key=dest_key işareti her defasında bir tuşun yerine kullanılacak tuşu belirtir.
  • --default_key_mappings dir işareti, build/target/product/security içindeki tüm anahtarları değiştirmek için beş anahtarlı bir dizin belirtir. Bu, eşlemeleri belirtmek için --key_mapping öğesini beş kez kullanmaya eşdeğerdir.
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

APK adlarına göre imzalama anahtarı değiştirmelerini belirtmek için --extra_apks apk_name1,apk_name2,...=key işaretini kullanın. key boş bırakılırsa komut dosyası, belirtilen APK'ları önceden imzalanmış olarak kabul eder.

Varsayımsal tardis ürünü için altı şifre korumalı anahtara ihtiyacınız var: beşi build/target/product/security içindeki beş anahtarın yerine, biri de yukarıdaki örnekte SpecialApp tarafından gerekli olan ek anahtar device/yoyodyne/security/special'ın yerine. Anahtarlar aşağıdaki dosyalardaysa:

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

Ardından tüm uygulamaları şu şekilde imzalarsınız:

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

Bu işlem sonucunda aşağıdakiler gösterilir:

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.

Kullanıcıdan şifre korumalı tüm anahtarların şifrelerini girmesini isteyen komut dosyası, giriş hedefindeki .zip tüm APK dosyalarını yayın anahtarlarıyla yeniden imzalar. Komutu çalıştırmadan önce ANDROID_PW_FILE ortam değişkenini geçici bir dosya adına da ayarlayabilirsiniz. Ardından komut dosyası, tüm anahtarların şifrelerini girmenize olanak tanımak için düzenleyicinizi çağırır (bu, şifreleri girmenin daha kolay bir yolu olabilir).

APEX imzalama anahtarı değiştirme

Android 10, daha düşük seviyeli sistem modüllerini yüklemek için APEX dosya biçimini kullanıma sunar. APEX imzalama bölümünde açıklandığı gibi, her APEX dosyası iki anahtarla imzalanır: biri APEX içindeki mini dosya sistemi görüntüsü, diğeri ise APEX'in tamamı için.

Yayın için imzalama yapılırken bir APEX dosyasının iki imzalama anahtarı, yayın anahtarlarıyla değiştirilir. Dosya sistemi yük anahtarı --extra_apex_payload işaretiyle, APEX dosyasının tamamının imzalama anahtarı ise --extra_apks işaretiyle belirtilir.

Tardis ürünü için com.android.conscrypt.apex, com.android.media.apex ve com.android.runtime.release.apex APEX dosyalarıyla ilgili aşağıdaki anahtar yapılandırmasına sahip olduğunuzu varsayın.

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"

Ayrıca, yayınlama anahtarlarını içeren aşağıdaki dosyalarınız varsa:

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

Aşağıdaki komut, yayın imzalama sırasında com.android.runtime.release.apex ve com.android.tzdata.apex için imzalama anahtarlarını geçersiz kılar. Özellikle, com.android.runtime.release.apex belirtilen yayın anahtarlarıyla imzalanır (APEX dosyası için runtime_apex_container ve dosya resmi yükü için runtime_apex_payload). com.android.tzdata.apex, önceden imzalanmış olarak kabul edilir. Diğer tüm APEX dosyaları, hedef dosyalarda listelenen varsayılan yapılandırma tarafından işlenir.

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

Yukarıdaki komut çalıştırıldığında aşağıdaki günlükler verilir:

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

Diğer seçenekler

sign_target_files_apks İmzalama komut dosyası, derlemenin imzalı bir derleme olduğunu yansıtmak için derleme özellikleri dosyalarındaki derleme açıklamasını ve parmak izini yeniden yazar. --tag_changes işareti, parmak izinde hangi düzenlemelerin yapılacağını kontrol eder. Tüm işaretlerle ilgili dokümanları görmek için komut dosyasını -h ile çalıştırın.

Anahtarları manuel olarak oluşturma

Android, genel üssü 3 olan 2048 bit RSA anahtarları kullanır. openssl.org adresindeki openssl aracını kullanarak sertifika/özel anahtar çiftleri oluşturabilirsiniz:

# 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

Yukarıda verilen openssl pkcs8 komutu, derleme sistemiyle kullanıma uygun, şifresiz bir .pk8 dosyası oluşturur. Şifreyle güvenli hale getirilmiş bir .pk8 oluşturmak için (tüm gerçek yayın anahtarları için yapmanız gerekir) -nocrypt bağımsız değişkenini -passout stdin ile değiştirin. Ardından openssl, özel anahtarı standart girişten okunan bir şifreyle şifreler. İstem yazdırılmaz. Bu nedenle, stdin terminal ise program aslında yalnızca şifre girmenizi beklerken askıda kalmış gibi görünür. Şifreyi diğer konumlardan okumak için -passout bağımsız değişkeninde başka değerler de kullanılabilir. Ayrıntılar için openssl belgelerine bakın.

temp.pem ara dosyası, özel anahtarı herhangi bir şifre koruması olmadan içerir. Bu nedenle, yayın anahtarları oluştururken bu dosyayı dikkatli bir şekilde imha edin. Özellikle GNUshred yardımcı programı, ağ veya günlük kaydı tutulan dosya sistemlerinde etkili olmayabilir. Ara ürünlerin yanlışlıkla açığa çıkmamasını sağlamak için anahtar oluştururken RAM diskte (ör. tmpfs bölümü) bulunan bir çalışma dizini kullanabilirsiniz.

Resim dosyaları oluşturma

signed-target_files.zip olduğunda, resmi bir cihaza yerleştirebilmek için oluşturmanız gerekir. Hedef dosyalardan imzalı görüntüyü oluşturmak için Android ağacının kökünden aşağıdaki komutu çalıştırın:

img_from_target_files signed-target_files.zip signed-img.zip
Elde edilen signed-img.zip dosyası, tüm .img dosyalarını içerir. Bir cihaza resim yüklemek için fastboot'u aşağıdaki şekilde kullanın:
fastboot update signed-img.zip