APK İmza Şeması v2

APK Signature Scheme v2, APK'nın korunan kısımlarında yapılan değişiklikleri tespit ederek doğrulama hızını artıran ve bütünlük garantilerini güçlendiren bir tam dosya imza şemasıdır.

APK İmza Şeması v2 kullanılarak imzalanması, APK dosyasına ZIP Merkezi Dizin bölümünün hemen öncesine bir APK İmzalama Bloğu ekler. APK İmzalama Bloğunun içinde, v2 imzaları ve imzalayanın kimlik bilgileri APK İmza Şeması v2 Bloğunda saklanır.

APK imzalamadan önce ve sonra

Şekil 1. APK imzalamadan önce ve sonra

APK İmza Şeması v2, Android 7.0'da (Nougat) tanıtıldı. Bir APK'nın Android 6.0 (Marshmallow) ve daha eski cihazlara yüklenebilmesi için APK'nın v2 şemasıyla imzalanmadan önce JAR imzalama kullanılarak imzalanması gerekir.

APK İmzalama Bloğu

v1 APK formatıyla geriye dönük uyumluluğu sürdürmek için v2 ve daha yeni APK imzaları, APK Signature Scheme v2'yi desteklemek üzere sunulan yeni bir kapsayıcı olan APK İmzalama Bloğunda saklanır. Bir APK dosyasında APK İmza Bloğu, dosyanın sonunda bulunan ZIP Merkezi Dizininin hemen önünde bulunur.

Blok, APK'da bloğun yerini bulmayı kolaylaştıracak şekilde sarılmış kimlik değeri çiftleri içerir. APK'nın v2 imzası, 0x7109871a kimliğine sahip bir kimlik-değer çifti olarak depolanır.

Biçim

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

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

APK, önce ZIP Merkezi Dizinin başlangıcı bulunarak ayrıştırılır (dosyanın sonunda Merkezi Dizinin ZIP Sonu kaydı bulunarak, ardından kayıttan Merkezi Dizinin başlangıç ​​ofseti okunarak). magic değer, Merkezi Dizin'den önce gelen şeyin muhtemelen APK İmzalama Bloğu olduğunu belirlemenin hızlı bir yolunu sağlar. size of block daha sonra verimli bir şekilde dosyadaki bloğun başlangıcını işaret eder.

Blok yorumlanırken bilinmeyen kimliklere sahip kimlik değeri ç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 APK İmza Şeması v2 Bloğu olarak saklanır. Her imzalayan için aşağıdaki bilgiler saklanır:

  • (imza algoritması, özet, imza) tanımlama grupları. Özet, imza doğrulamasını APK içeriğinin bütünlük kontrolünden 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 dikkate alınmaz. Birden fazla desteklenen imzayla karşılaşıldığında hangi imzanın kullanılacağını seçmek her uygulamaya bağlıdır. Bu, gelecekte daha güçlü imzalama yöntemlerinin geriye dönük olarak uyumlu bir şekilde tanıtılmasına olanak tanır. Önerilen yaklaşım en güçlü imzanın doğrulanmasıdır.

Biçim

APK İmza Şeması v2 Bloğu, APK İmzalama Bloğunun içinde 0x7109871a kimliği altında saklanır.

APK İmza Şeması v2 Bloğunun formatı aşağıdaki gibidir (tüm sayısal değerler little-endian'dır, tüm uzunluk önekli alanlar uzunluk için uint32 kullanır):

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

İmza Algoritması Kimlikleri

  • 0x0101—RSASSA-PSS, SHA2-256 özeti, SHA2-256 MGF1, 32 bayt tuz, fragman: 0xbc
  • 0x0102—RSASSA-PSS, SHA2-512 özeti, SHA2-512 MGF1, 64 bayt tuz, fragman: 0xbc
  • 0x0103—RSASSA-PKCS1-v1_5, SHA2-256 özetiyle. Bu, deterministik imzalar gerektiren yapı sistemleri içindir.
  • 0x0104—RSASSA-PKCS1-v1_5, SHA2-512 özetiyle. Bu, deterministik imzalar gerektiren yapı sistemleri içindir.
  • 0x0201—SHA2-256 özetiyle ECDSA
  • 0x0202—SHA2-512 özetiyle ECDSA
  • 0x0301—SHA2-256 özetiyle 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çeriklerini korumak amacıyla bir APK dört bölümden oluşur:

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

İmzalamadan sonra APK bölümleri

Şekil 2. İmzalama sonrası APK bölümleri

APK İmza Şeması v2, 1, 3, 4. bölümlerin ve bölüm 2'de yer alan APK İmza Şeması v2 Bloğunun signed data bloklarının bütünlüğünü korur.

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

Bölüm 1, 3 ve 4'ün özeti, iki seviyeli Merkle ağacına benzer şekilde aşağıdaki şekilde hesaplanır. Her bölüm ardışık 1 MB'lık (2 20 bayt) parçalara bölünmüştür. Her bölümdeki son parça daha kısa olabilir. Her bir parçanın özeti, 0xa5 baytının, parçanın bayt cinsinden uzunluğunun (little-endian uint32) ve parçanın içeriğinin birleştirilmesi üzerinden hesaplanır. Üst düzey özet, bayt 0x5a birleştirilmesi, parça sayısı (little-endian uint32) ve parçaların APK'da görünme sırasına göre parçaların özetlerinin birleştirilmesi üzerinden hesaplanır. Özet, hesaplamayı paralelleştirerek hızlandırmak için parçalanmış şekilde hesaplanır.

APK özeti

Şekil 3. APK özeti

Bölüm 4'ün (Merkezi Dizinin ZIP Sonu) korunması, ZIP Merkezi Dizinin ofsetini içeren bölüm nedeniyle karmaşık hale gelir. APK İmza Bloğunun boyutu değiştiğinde (örneğin yeni bir imza eklendiğinde) ofset değişir. Bu nedenle, Merkezi Dizinin ZIP Sonu üzerinden özet hesaplanırken, ZIP Merkezi Dizinin ofsetini içeren alan, APK İmza Bloğunun ofsetini içeriyormuş gibi 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ı sağlamaya çalışabilir. Bu saldırıyı azaltmak için, aynı zamanda v1 imzalı olan v2 imzalı APK'ların, META-INF/*.SF dosyalarının ana bölümünde bir X-Android-APK-Signed özelliği içermesi gerekir. Özelliğin değeri, virgülle ayrılmış bir APK imza şeması kimlikleri kümesidir (bu şemanın kimliği 2'dir). V1 imzasını doğrularken, APK doğrulayıcının bu setten tercih ettiği APK imza şemasına (örn. v2 şeması) yönelik imzası olmayan APK'ları reddetmesi gerekir. Bu koruma, META-INF/*.SF dosyalarının içeriğinin v1 imzalarıyla korunmasına dayanır. JAR imzalı APK doğrulaması bölümüne bakın.

Bir saldırgan, APK İmza Şeması v2 Bloğundan daha güçlü imzaları kaldırmaya çalışabilir. Bu saldırıyı azaltmak için APK'nın imzalandığı imza algoritması kimliklerinin listesi, her imza tarafından korunan signed data bloğunda saklanır.

Doğrulama

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

APK imza doğrulama süreci

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

APK İmza Şeması v2 doğrulaması

  1. APK İmzalama Bloğunu bulun ve şunları doğrulayın:
    1. APK İmzalama Bloğunun iki boyutlu alanı aynı değeri içerir.
    2. ZIP Merkezi Dizininin hemen ardından Merkezi Dizinin ZIP Sonu kaydı gelir.
    3. Merkezi Dizinin ZIP Sonu daha fazla veri tarafından takip edilmez.
  2. APK İmzalama Bloğunun içindeki ilk APK İmza Şeması v2 Bloğunu bulun. v2 Bloğu mevcutsa 3. adıma geçin. Aksi takdirde v1 şemasını kullanarak APK'yı doğrulamaya geri dönün.
  3. APK İmza Şeması v2 Bloğundaki her signer için:
    1. signatures desteklenen en güçlü signature algorithm ID seçin. Güç sıralaması her uygulama/platform sürümüne bağlıdır.
    2. signatures karşılık gelen signature public key kullanarak signed data doğrulayın. ( signed data ayrıştırmak artık güvenlidir.)
    3. digests ve signatures imza algoritması kimliklerinin sıralı listesinin aynı olduğunu doğrulayın. (Bu, imzanın çıkarılmasını/eklenmesini önlemek içindir.)
    4. APK içeriklerinin özetini, imza algoritması tarafından kullanılan özet algoritmasıyla aynı özet algoritmasını kullanarak hesaplayın .
    5. Hesaplanan özetin, digests karşılık gelen digest aynı olduğunu doğrulayın.
    6. İlk certificates certificate SubjectPublicKeyInfo değerinin 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ı olursa doğrulama başarılı olur.

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

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

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

  1. Her imzalayan, bir META-INF/<imzalayan>.SF ve META-INF/<imzalayan>.(RSA|DSA|EC) JAR girişiyle 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 tüm dosya özeti doğrulandı. 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ğrulanmıştı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.

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