APK İmza Şeması v2

APK Signature Scheme v2, APK'nın korunan bölümlerindeki değişiklikleri algılayarak doğrulama hızını artıran ve bütünlük garantilerini güçlendiren tam dosya imza şemasıdır.

APK Signature Scheme v2 kullanarak imzalamak, APK dosyasına ZIP Central Directory bölümünden hemen önce bir APK İmzalama Bloğu ekler. APK İmzalama Bloğu içinde, v2 imzaları ve imzalayan kimlik bilgileri bir APK İmza Şeması v2 Bloğunda depolanır.

APK imzalamadan önce ve sonra

Şekil 1. APK imzalamadan önce ve sonra

APK Signature Scheme v2, Android 7.0'da (Nougat) kullanıma sunuldu. Bir APK'yı Android 6.0 (Marshmallow) ve daha eski cihazlara yüklenebilir hale getirmek için APK, v2 şemasıyla imzalanmadan önce JAR imzası kullanılarak imzalanmalıdır.

APK İmzalama Bloğu

v1 APK biçimiyle geriye dönük uyumluluğu korumak için v2 ve daha yeni APK imzaları, APK Signature Scheme v2'yi desteklemek üzere tanıtılan yeni bir kapsayıcı olan APK İmzalama Bloğu içinde depolanır. Bir APK dosyasında, APK İmza Bloğu, dosyanın sonunda bulunan ZIP Merkez Dizininin hemen önünde bulunur.

Blok, APK'da bloğu bulmayı kolaylaştıracak şekilde sarılmış kimlik değeri çiftleri içerir. APK'nın v2 imzası, ID 0x7109871a ile bir ID-değer çifti olarak saklanır.

Biçim

APK İmza Bloğunun formatı aşağıdaki gibidir (tüm sayısal alanlar küçük endian'dır):

  • bayt cinsinden size of block (bu alan hariç) (uint64)
  • uint64-uzunluk-ön ekli ID-değer çiftlerinin sırası:
    • ID (uint32)
    • value (değişken uzunluk: çiftin uzunluğu - 4 bayt)
  • bayt cinsinden size of block —ilk alanla aynı (uint64)
  • magic “APK Sig Block 42” (16 bayt)

APK, önce ZIP Merkez Dizininin başlangıcını bularak (dosyanın sonundaki Merkez Dizinin ZIP Sonu kaydını bularak, ardından Kayıttan Merkezi Dizinin başlangıç ​​uzaklığını okuyarak) ayrıştırılır. magic değer, Central Directory'den önce gelenin büyük olasılıkla APK İmzalama Bloğu olduğunu belirlemenin hızlı bir yolunu sağlar. size of block daha sonra etkin bir şekilde dosyadaki bloğun başlangıcına işaret eder.

Blok yorumlanırken bilinmeyen ID'lere sahip ID-değer çiftleri göz ardı edilmelidir.

APK İmza Şeması v2 Bloğu

APK, her biri bir imzalama anahtarıyla temsil edilen bir veya daha fazla imzalayan/kimlik tarafından imzalanır. Bu bilgiler bir APK Signature Scheme v2 Block olarak saklanır. Her imzalayan için aşağıdaki bilgiler saklanır:

  • (imza algoritması, özet, imza) demetleri. Özet, APK içeriğinin bütünlük kontrolünden imza doğrulamasını ayırmak için saklanır.
  • İmzalayanın kimliğini temsil eden X.509 sertifika zinciri.
  • Anahtar/değer çiftleri olarak ek özellikler.

Her imzalayan için APK, sağlanan listeden desteklenen bir imza kullanılarak doğrulanır. Bilinmeyen imza algoritmalarına sahip imzalar yoksayılır. Desteklenen birden çok imzayla karşılaşıldığında hangi imzanın kullanılacağını seçmek her uygulamaya bağlıdır. Bu, gelecekte geriye dönük uyumlu bir şekilde daha güçlü imzalama yöntemlerinin sunulmasını sağlar. Önerilen yaklaşım, en güçlü imzayı doğrulamaktır.

Biçim

APK Signature Scheme v2 Block, APK İmzalama Bloğu içinde 0x7109871a kimliği altında depolanır.

APK Signature Scheme v2 Block'un formatı aşağıdaki gibidir (tüm sayısal değerler küçük endiandır, tüm uzunluk önekli alanlar uzunluk için uint32 kullanır):

  • uzunluk önekli signer uzunluk öneki dizisi:
    • uzunluk ön ekli signed data :
      • uzunluk ön ekli digests uzunluk ön ekli dizisi :
      • X.509 certificates uzunluk ön ekli dizisi :
        • uzunluk ön ekli X.509 certificate (ASN.1 DER formu)
      • uzunluk önekli additional attributes dizisi:
        • ID (uint32)
        • value (değişken uzunluk: ek özelliğin uzunluğu - 4 bayt)
    • uzunluk önekli signatures uzunluk öneki dizisi:
      • signature algorithm ID (uint32)
      • signed data üzerinde uzunluk ön ekli signature
    • uzunluk önekli public key (SubjectPublicKeyInfo, ASN.1 DER formu)

İmza Algoritması Kimlikleri

  • 0x0101—SHA2-256 özetli RSASSA-PSS, SHA2-256 MGF1, 32 bayt tuz, fragman: 0xbc
  • 0x0102—RSASSA-PSS, SHA2-512 özet, SHA2-512 MGF1, 64 bayt tuz, fragman: 0xbc
  • 0x0103—RSASSA-PKCS1-v1_5, SHA2-256 özeti ile. Bu, deterministik imzalar gerektiren yapı sistemleri içindir.
  • 0x0104—RSASSA-PKCS1-v1_5, SHA2-512 özeti ile. Bu, deterministik imzalar gerektiren yapı sistemleri içindir.
  • 0x0201—SHA2-256 özetli ECDSA
  • 0x0202—SHA2-512 özetli ECDSA
  • 0x0301—SHA2-256 özetli DSA

Yukarıdaki imza algoritmalarının tümü Android platformu tarafından desteklenmektedir. İmzalama araçları, algoritmaların bir alt kümesini destekleyebilir.

Desteklenen tuş boyutları ve EC eğrileri:

  • RSA: 1024, 2048, 4096, 8192, 16384
  • EC: NIST P-256, P-384, P-521
  • DSA: 1024, 2048, 3072

Bütünlük korumalı içerikler

APK içeriğini korumak amacıyla bir APK dört bölümden oluşur:

  1. ZIP girişlerinin içeriği (0 ofsetinden APK İmza Bloğunun başlangıcına kadar)
  2. APK İmzalama Bloğu
  3. ZIP Merkez Dizini
  4. Merkez Dizinin ZIP Sonu

İmzaladıktan sonra APK bölümleri

Şekil 2. İmzalandıktan sonra APK bölümleri

APK Signature Scheme v2, bölüm 1, 3, 4'ün bütünlüğünü ve bölüm 2'de bulunan APK Signature Scheme v2 Block'un signed data bloklarını korur.

Bölüm 1, 3 ve 4'ün bütünlüğü, bir veya daha fazla imza ile korunan signed data bloklarında saklanan içeriklerinin bir veya daha fazla özeti ile korunur.

1, 3 ve 4 bölümleri üzerindeki özet, iki seviyeli Merkle ağacına benzer şekilde aşağıdaki gibi hesaplanır. Her bölüm ardışık 1 MB (2 20 bayt) parçalara bölünür. Her bölümdeki son parça daha kısa olabilir. Her yığının özeti, bayt 0xa5 , yığının bayt cinsinden uzunluğu (little-endian uint32) ve yığının içeriği üzerinden hesaplanır. Üst düzey özet, bayt 0x5a birleştirilmesi, parçaların sayısı (little-endian uint32) ve parçaların APK'da göründüğü sırayla parçaların özetlerinin birleştirilmesi üzerinden hesaplanır. Özet, paralel hale getirerek hesaplamayı hızlandırmak için yığın şeklinde hesaplanır.

APK özeti

Şekil 3. APK özeti

4. bölümün (Merkezi Dizinin ZIP Sonu) korunması, ZIP Merkez Dizininin ofsetini içeren bölüm nedeniyle karmaşıktır. APK İmza Bloğunun boyutu değiştiğinde, örneğin yeni bir imza eklendiğinde, ofset değişir. Bu nedenle, Merkez Dizinin ZIP Sonu üzerinden özet hesaplanırken, ZIP Merkez Dizininin ofsetini içeren alan, APK İmzalama Bloğunun ofsetini içeriyor olarak ele alınmalıdır.

Geri Alma Korumaları

Saldırgan, v2 imzalı APK'nın doğrulanmasını destekleyen Android platformlarında v2 imzalı bir APK'nın v1 imzalı APK olarak doğrulanmasını deneyebilir. Bu saldırıyı azaltmak için v1 imzalı olan v2 imzalı APK'lar, META-INF/*.SF dosyalarının ana bölümünde bir X-Android-APK-Signed özniteliği içermelidir. Özniteliğin değeri, virgülle ayrılmış bir dizi APK imza şeması kimliğidir (bu şemanın kimliği 2'dir). v1 imzasını doğrularken, doğrulayıcının bu kümeden tercih ettiği APK imza şeması için imzası olmayan APK'ları reddetmek için APK doğrulayıcı gerekir (ör. v2 şeması). Bu koruma, META-INF/*.SF dosyalarının içeriğinin v1 imzalarıyla korunması gerçeğine dayanır. JAR imzalı APK doğrulaması ile ilgili bölüme bakın.

Saldırgan, APK Signature Scheme v2 Block'tan daha güçlü imzaları kaldırmaya çalışabilir. Bu saldırıyı azaltmak için APK'nın imzalandığı imza algoritması kimliklerinin listesi, her bir imza tarafından korunan signed data bloğunda saklanır.

Doğrulama

Android 7.0 ve sonraki sürümlerde APK'lar, APK Signature Scheme v2+ veya JAR imzalamaya (v1 şeması) göre doğrulanabilir. Daha eski platformlar v2 imzalarını yok sayar ve yalnızca v1 imzalarını doğrular.

APK imza doğrulama işlemi

Şekil 4. APK imza doğrulama süreci (kırmızı ile yeni adımlar)

APK İmza Şeması v2 doğrulaması

  1. APK İmzalama Bloğu'nu bulun ve şunları doğrulayın:
    1. APK Signing Block'un iki boyut alanı aynı değeri içerir.
    2. ZIP Central Directory'nin hemen ardından ZIP End of Central Directory kaydı gelir.
    3. ZIP End of Central Directory daha fazla veri tarafından takip edilmez.
  2. APK İmzalama Bloğu içindeki ilk APK İmza Şeması v2 Bloğu'nu bulun. v2 Bloğu varsa, 3. adıma geçin. Aksi takdirde, v1 şemasını kullanarak APK'yı doğrulamaya geri dönün.
  3. APK İmza Planı v2 Bloğundaki her signer için:
    1. İmzalardan desteklenen en güçlü signatures signature algorithm ID seçin. Güç sıralaması her uygulama/platform versiyonuna bağlıdır.
    2. public key kullanarak signed data karşı signatures karşılık gelen signature doğrulayın. ( signed data ayrıştırmak artık güvenlidir.)
    3. digests ve signatures sıralı imza algoritması kimlikleri listesinin aynı olduğunu doğrulayın. (Bu, imzanın çıkarılmasını/eklenmesini önlemek içindir.)
    4. İmza algoritması tarafından kullanılan özet algoritmasıyla aynı özet algoritmasını kullanarak APK içeriğinin özetini hesaplayın .
    5. Hesaplanan özetin, digests karşılık gelen digest aynı olduğunu doğrulayın.
    6. İlk certificate certificates public key aynı olduğunu doğrulayın.
  4. En az bir signer bulunursa ve bulunan her signer için 3. adım başarılıysa doğrulama başarılı olur.

Not : 3. veya 4. adımda bir hata oluşursa APK v1 şeması kullanılarak doğrulanmamalıdır.

JAR imzalı APK doğrulaması (v1 şeması)

JAR imzalı APK, tam olarak META-INF/MANIFEST.MF içinde listelenen girişleri içermesi ve tüm girişlerin aynı imzalayanlar tarafından imzalanması gereken standart imzalı bir JAR'dır. Bütünlüğü şu şekilde doğrulanır:

  1. Her imzalayan bir META-INF/<signer>.SF ve META-INF/<signer>.(RSA|DSA|EC) JAR girişi ile temsil edilir.
  2. <signer>.(RSA|DSA|EC), imzası <signer>.SF dosyası üzerinden doğrulanan SignedData yapısına sahip bir PKCS #7 CMS ContentInfo'dur.
  3. <signer>.SF dosyası, META-INF/MANIFEST.MF'nin tam dosya özetini ve META-INF/MANIFEST.MF'nin her bölümünün özetini içerir. MANIFEST.MF'nin tam dosya özeti doğrulanır. Bu başarısız olursa, bunun yerine her MANIFEST.MF bölümünün özeti doğrulanır.
  4. META-INF/MANIFEST.MF, bütünlük korumalı her JAR girişi için, girişin sıkıştırılmamış içeriğinin özetini içeren, uygun şekilde adlandırılmış bir bölüm içerir. Tüm bu özetler doğrulanır.
  5. APK, MANIFEST.MF'de listelenmeyen ve JAR imzasının parçası olmayan JAR girişleri içeriyorsa APK doğrulaması başarısız olur.

Bu nedenle koruma zinciri, bütünlük korumalı her JAR girişinin <signer>.(RSA|DSA|EC) -> <signer>.SF -> MANIFEST.MF -> içeriğidir.