Derlemeleri yayınlamak için imzalayın

Android OS resimleri, kriptografik imzaları iki yerde kullanır:

  1. Resmin içindeki her .apk dosyası imzalanmalıdır. Android'in Paket Yöneticisi, .apk imzasını iki şekilde kullanır:
    • Değiştirilen bir uygulama, eski uygulamanın verilerine erişebilmek için eski uygulamayla aynı anahtarla imzalanmalıdır. Bu, hem .apk öğesinin üzerine yazarak kullanıcı uygulamalarını güncellemek hem de /data altında daha yeni bir sürüm yüklü bir sistem uygulamasını geçersiz kılmak için geçerlidir.
    • İki veya daha fazla uygulama bir kullanıcı kimliğini paylaşmak istiyorsa (veri vb. paylaşabilmek için) aynı anahtarla imzalanmış olmalıdır.
  2. OTA güncelleme paketleri, sistem tarafından beklenen anahtarlardan biriyle imzalanmalıdır. Aksi takdirde yükleme işlemi bunları reddeder.

Yayın anahtarları

Android ağacı, build/target/product/security altında test-keys içerir. make kullanılarak bir Android OS görüntüsü oluşturulduğunda, tüm .apk dosyaları test anahtarları kullanılarak imzalanır. Test anahtarları herkes tarafından bilindiği için herkes kendi .apk dosyalarını aynı anahtarlarla imzalayabilir. Bu da onların işletim sistemi görüntünüzde yerleşik olarak bulunan sistem uygulamalarını değiştirmesine veya ele geçirmesine olanak tanıyabilir. Bu nedenle, herkese açık olarak yayınlanan veya dağıtılan tüm Android OS imajlarının yalnızca size ait özel bir sürüm anahtarı grubuyla imzalanması önemlidir.

Kendi benzersiz sürüm anahtarlarınızı 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. İstediğiniz dizini kullanabilirsiniz ancak yedeklenen ve güvenli bir konum seçmeye dikkat edin. Bazı tedarikçiler, özel anahtarlarını güçlü bir şifre ifadesiyle şifreleyip şifrelenmiş anahtarı kaynak denetiminde saklamayı tercih eder. Diğerleri ise yayın anahtarlarını tamamen başka bir yerde (ör. internete bağlı olmayan bir bilgisayarda) saklar.

Sürüm resmi oluşturmak için:

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 signed-target_files.zip'da IMAGES/ altında bulabilirsiniz.

OTA paketlerini imzalama

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

İmzalar ve harici yükleme

Başka cihazdan yükleme, kurtarmanın normal paket imzası doğrulama mekanizmasını atlamaz. Bir paket yüklemeden önce kurtarma işlemi, internet üzerinden teslim edilen bir pakette olduğu gibi, kurtarma bölümünde depolanan ortak anahtarlarla eşleşen özel anahtarlardan biriyle imzalandığını doğrular.

Ana sistemden alınan güncelleme paketleri genellikle bir kez ana sistem tarafından, biri Android API'de RecoverySystem.verifyPackage() yöntemi kullanılarak, sonra da kurtarma işlemiyle olmak üzere iki kez doğrulanır. RecoverySystem API, imzayı ana sistemde (varsayılan olarak) /system/etc/security/otacerts.zip dosyasında depolanan ortak anahtarlarla karşılaştırır. Kurtarma, imzayı kurtarma bölümü RAM diskinde /res/keys dosyasında depolanan ortak anahtarlarla karşılaştırır.

Derleme işlemi tarafından oluşturulan hedef dosyalar .zip varsayılan olarak OTA sertifikasını test anahtarıyla eşleşecek şekilde ayarlar. Cihazların güncelleme paketinin özgünlüğünü doğrulayabilmesi için yayınlanan resimde farklı bir sertifika kullanılmalıdır. Önceki bölümde gösterildiği gibi -o işaretçisini sign_target_files_apks değerine ilettiğinizde test anahtarı sertifikası, certs dizininizdeki yayın anahtarı sertifikasıyla değiştirilir.

Normalde sistem görüntüsü ve kurtarma görüntüsü aynı OTA açık anahtar grubunu depolar. Yalnızca kurtarma anahtar grubuna bir anahtar ekleyerek yalnızca harici yükleme yoluyla yüklenebilen paketleri imzalamak mümkündür (ana sistemin güncelleme indirme mekanizmasının otacerts.zip ile doğru şekilde doğrulama yaptığı varsayılır). Ürün tanımınıza PRODUCT_EXTRA_RECOVERY_KEYS değişkenini ekleyerek yalnızca kurtarma işlemine dahil edilecek ek anahtarları belirtebilirsiniz:

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

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

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

Sertifikalar ve özel anahtarlar

Her anahtar iki dosyada gelir: .x509.pem uzantılı sertifika ve .pk8 uzantılı özel anahtar. Özel anahtar gizli tutulmalıdır ve paketi imzalamak için gereklidir. Anahtar da şifreyle korunabilir. Sertifika ise anahtarın yalnızca herkese açık yarısını içerir. Bu nedenle, geniş bir kitleye dağıtılabilir. Bir paketin ilgili özel anahtarla imzalanıp imzalanmadığını doğrulamak için kullanılır.

Standart Android derlemesi, tümü build/target/product/security içinde bulunan beş anahtar kullanır:

testkey
Anahtar belirtmeyen paketler için genel varsayılan anahtar.
platform
Temel platformun parçası olan paketler için test anahtarı.
paylaşıldı
Ev/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 bir parçası olan paketler için test anahtarı. Networkstack anahtarı, Modüler Sistem Bileşenleri olarak tasarlanan ikili programları imzalamak için kullanılır. Modül güncellemeleriniz ayrı olarak derlenip cihaz resminize önceden derlenmiş olarak entegre edildiyse Android kaynak ağacında bir ağ yığın anahtarı oluşturmanız gerekmeyebilir.

Ayrı paketler, Android.mk dosyalarında LOCAL_CERTIFICATE'ı ayarlayarak bu anahtarlardan birini belirtir. (Bu değişken ayarlanmamışsa testkey kullanılır.) 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 derleme, SpecialApp.apk'yı imzalamak için device/yoyodyne/security/special.{x509.pem,pk8} anahtarını kullanıyor. Derleme yalnızca şifre korumalı olmayan özel anahtarları kullanabilir.

Gelişmiş imzalama seçenekleri

APK imzalama anahtarı değişimi

İ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. Sürüm imzalamak için imzalama komut dosyasını çalıştırırken imzalama anahtarları, anahtar adına veya APK adına göre değiştirilebilir.

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

  • --key_mapping src_key=dest_key işareti, tek seferde bir anahtarın değiştirileceğini belirtir.
  • --default_key_mappings dir işaretçisi, build/target/product/security içindeki tüm anahtarları değiştirmek için beş anahtar içeren bir dizin belirtir. Bu, eşlemeleri belirtmek için --key_mapping değerini 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

İmzalama anahtarı değişimlerini APK adlarına göre 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 değerlendirir.

Hayali tardis ürünü için altı şifre korumalı anahtara ihtiyacınız vardır: build/target/product/security'teki beş anahtarı değiştirmek için beş ve yukarıdaki örnekte SpecialApp tarafından istenen ek device/yoyodyne/security/special anahtarını değiştirmek için bir anahtar. Anahtarlar aşağıdaki dosyalarda bulunuyorsa:

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

Bu durumda 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

Bunun sonucunda aşağıdakiler ortaya çıkar:

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.

Komut dosyası, kullanıcıdan şifre korumalı tüm anahtarların şifrelerini istedikten sonra giriş hedefindeki .zip tüm APK dosyalarını sürüm anahtarlarıyla yeniden imzalar. Komutu çalıştırmadan önce ANDROID_PW_FILE ortam değişkenini geçici bir dosya adına da ayarlayabilirsiniz. Bu durumda komut dosyası, tüm anahtarların şifrelerini girmenize izin vermek için düzenleyicinizi çağırır (bu, şifre girmenin daha uygun bir yolu olabilir).

APEX imzalama anahtarı değişimi

Android 10'da, alt düzey sistem modüllerini yüklemek için APEX dosya biçimi kullanıma sunulmuştur. APEX imzalama bölümünde açıklandığı gibi, her APEX dosyası iki anahtarla imzalanır: biri APEX içindeki mini dosya sistemi resmi için, diğeri ise APEX'in tamamı için.

Sürüm için imza atarken APEX dosyasındaki iki imzalama anahtarı, serbest bırakma anahtarlarıyla değiştirilir. Dosya sistemi yükü anahtarı --extra_apex_payload işaretiyle, APEX dosya imzalama anahtarının tamamı 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ı için aşağıdaki anahtar yapılandırmasına sahip olduğunuzu varsayalım.

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, sürüm anahtarlarını içeren aşağıdaki dosyalarınız olmalıdır:

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, sürüm 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 görüntüsü yükü için runtime_apex_payload). com.android.tzdata.apex, önceden imzalanmış olarak değerlendirilir. Diğer tüm APEX dosyaları, hedef dosyalarda listelendiği şekilde varsayılan yapılandırmaya göre 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 komutu çalıştırdığınızda aşağıdaki günlükler gösterilir:

        [...]
    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 imzalama komut dosyası, derleme özelliklerinin dosyalarındaki derleme açıklamasını ve parmak izini, derlemenin imzalı bir derleme olduğunu yansıtacak şekilde yeniden yazar. --tag_changes işareti, parmak izinde hangi düzenlemelerin yapıldığı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, ortak üs 3 ile 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ılmaya uygun, şifre içermeyen bir .pk8 dosyası oluşturur. Şifreyle korunan bir .pk8 dosyası oluşturmak için (tüm gerçek sürüm 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 şifre girmenizi beklerken takılmış gibi görünür. Şifrenin diğer konumlardan okunması için the-passout bağımsız değişkeni için başka değerler 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, sürüm anahtarları oluştururken bu dosyayı dikkatli bir şekilde silin. Özellikle GNUshred yardımcı programı, ağ veya günlük kaydı tutulan dosya sistemlerinde etkili olmayabilir. Araların yanlışlıkla açığa çıkarılmadığından emin olmak için anahtar oluştururken RAM diskinde bulunan çalışma dizinini (tmpfs bölümü gibi) kullanabilirsiniz.

Resim dosyası oluşturma

signed-target_files.zip'e sahip olduğunuzda, cihaza yerleştirebilmeniz için resmi oluşturmanız gerekir. Hedef dosyalardan imzalı görüntü 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
Oluşturulan signed-img.zip dosyası, tüm .img dosyalarını içerir. Bir cihaza resim yüklemek için fastboot'u aşağıdaki gibi kullanın:
fastboot update signed-img.zip