Skema tanda tangan APK v3

Android 9 mendukung rotasi kunci APK, yang memberi aplikasi kemampuan untuk mengubah kunci penandatanganan sebagai bagian dari update APK. Agar rotasi praktis, APK harus menunjukkan tingkat kepercayaan antara kunci penandatanganan baru dan lama. Untuk mendukung rotasi kunci, kami mengupdate skema tanda tangan APK dari v2 ke v3 agar kunci baru dan lama dapat digunakan. V3 menambahkan informasi tentang versi SDK yang didukung dan struct bukti rotasi ke blok penandatanganan APK.

Blok penandatanganan APK

Untuk mempertahankan kompatibilitas mundur dengan format APK v1, tanda tangan APK v2 dan v3 disimpan di dalam blok penandatanganan APK, yang terletak tepat sebelum ZIP Central Directory.

Format blok penandatanganan APK v3 sama dengan v2. Tanda tangan v3 APK disimpan sebagai pasangan nilai ID dengan ID 0xf05368c0.

Blok APK signature scheme v3

Skema v3 dirancang agar sangat mirip dengan skema v2. Format umumnya sama dan mendukung ID algoritma tanda tangan, ukuran kunci, dan kurva EC yang sama.

Namun, skema v3 menambahkan informasi tentang versi SDK yang didukung dan struktur bukti rotasi.

Format

Blok APK signature scheme v3 disimpan di dalam blok penandatanganan APK dengan ID 0xf05368c0.

Format blok APK signature scheme v3 mengikuti v2:

  • urutan signer yang diawali dengan panjang:
    • signed data dengan awalan panjang:
      • urutan digests yang diawali dengan panjang:
        • signature algorithm ID (4 byte)
        • digest (awalan panjang)
      • urutan certificates X.509 dengan awalan panjang:
        • certificate X.509 dengan awalan panjang (bentuk DER ASN.1)
      • minSDK (uint32) - penanda tangan ini harus diabaikan jika versi platform berada di bawah angka ini.
      • maxSDK (uint32) - penanda tangan ini harus diabaikan jika versi platform di atas angka ini.
      • urutan additional attributes yang diawali dengan panjang:
        • ID (uint32)
        • value (panjang variabel: panjang atribut tambahan - 4 byte)
        • ID - 0x3ba06f8c
        • value - Struktur bukti rotasi
    • minSDK (uint32) - duplikat nilai minSDK di bagian data yang ditandatangani - digunakan untuk melewati verifikasi tanda tangan ini jika platform saat ini tidak dalam rentang. Harus cocok dengan nilai data yang ditandatangani.
    • maxSDK (uint32) - duplikat nilai maxSDK di bagian data yang ditandatangani - digunakan untuk melewati verifikasi tanda tangan ini jika platform saat ini tidak berada dalam rentang. Harus cocok dengan nilai data yang ditandatangani.
    • urutan signatures yang diawali dengan panjang:
      • signature algorithm ID (uint32)
      • signature dengan awalan panjang di atas signed data
    • public key dengan awalan panjang (SubjectPublicKeyInfo, ASN.1 DER form)

Struktur bukti rotasi dan sertifikat lama tepercaya mandiri

Struktur bukti rotasi memungkinkan aplikasi memutar sertifikat penandatanganan tanpa diblokir di aplikasi lain yang digunakan untuk berkomunikasi. Untuk melakukannya, tanda tangan aplikasi berisi dua bagian data baru:

  • pernyataan untuk pihak ketiga bahwa sertifikat penandatanganan aplikasi dapat dipercaya di mana pun pendahulunya dipercaya
  • sertifikat penandatanganan lama aplikasi yang masih dipercaya aplikasi itu sendiri

Atribut proof-of-rotation di bagian data yang ditandatangani terdiri dari daftar dengan link tunggal, dengan setiap node berisi sertifikat penandatanganan yang digunakan untuk menandatangani versi aplikasi sebelumnya. Atribut ini dimaksudkan untuk berisi struktur data proof-of-rotation konseptual dan self-trusted-old-certs. Daftar ini diurutkan berdasarkan versi dengan sertifikat penandatanganan terlama yang sesuai dengan node root. Struktur data proof-of-rotation dibuat dengan meminta sertifikat di setiap node menandatangani sertifikat berikutnya dalam daftar, sehingga memberikan bukti ke setiap kunci baru bahwa kunci tersebut harus dipercaya seperti kunci lama.

Struktur data self-trusted-old-certs dibuat dengan menambahkan tanda ke setiap node yang menunjukkan keanggotaan dan propertinya dalam set. Misalnya, tanda mungkin ada yang menunjukkan bahwa sertifikat penandatanganan di node tertentu tepercaya untuk mendapatkan izin tanda tangan Android. Tanda ini memungkinkan aplikasi lain yang ditandatangani oleh sertifikat lama masih diberi izin tanda tangan yang ditentukan oleh aplikasi yang ditandatangani dengan sertifikat penandatanganan baru. Karena seluruh atribut bukti rotasi berada di bagian data yang ditandatangani di kolom signer v3, atribut tersebut dilindungi oleh kunci yang digunakan untuk menandatangani apk yang berisi.

Format ini mengecualikan beberapa kunci penanda tanganan dan konvergensi sertifikat penanda tanganan ancestor yang berbeda menjadi satu (beberapa node awal ke sink umum).

Format

Bukti rotasi disimpan di dalam blok APK signature scheme v3 dengan ID 0x3ba06f8c. Formatnya adalah:

  • urutan levels yang diawali dengan panjang:
    • signed data dengan awalan panjang (oleh sertifikat sebelumnya - jika ada)
      • certificate X.509 dengan awalan panjang (bentuk DER ASN.1)
      • signature algorithm ID (uint32) - algoritma yang digunakan oleh sertifikat di level sebelumnya
    • flags (uint32) - flag yang menunjukkan apakah sertifikat ini harus berada dalam struct self-trusted-old-certs atau tidak, dan untuk operasi mana.
    • signature algorithm ID (uint32) - harus cocok dengan yang ada di bagian data yang ditandatangani di tingkat berikutnya.
    • signature dengan awalan panjang di atas signed data di atas

Beberapa sertifikat

Beberapa penanda tangan tidak didukung dan Google Play tidak memublikasikan aplikasi yang ditandatangani dengan beberapa sertifikat.

Verifikasi

Di Android 9 dan yang lebih tinggi, APK dapat diverifikasi sesuai dengan APK Signature Scheme v3, skema v2, atau skema v1. Platform lama mengabaikan tanda tangan v3 dan mencoba memverifikasi tanda tangan v2, lalu v1.

Proses verifikasi tanda tangan APK

Gambar 1. Proses verifikasi tanda tangan APK

Verifikasi APK signature scheme v3

  1. Temukan blok penandatanganan APK dan pastikan bahwa:
    1. Dua kolom ukuran blok penandatanganan APK berisi nilai yang sama.
    2. Direktori Pusat ZIP segera diikuti dengan data Akhir Direktori Pusat ZIP.
    3. Akhir Direktori Pusat ZIP tidak diikuti dengan data lainnya.
  2. Temukan blok APK signature scheme v3 pertama di dalam blok penandatanganan APK. Jika blok v3 ada, lanjutkan ke langkah 3. Jika tidak, kembali ke verifikasi APK menggunakan skema v2.
  3. Untuk setiap signer dalam blok skema tanda tangan APK v3 dengan versi SDK min dan maks yang berada dalam rentang platform saat ini:
    1. Pilih signature algorithm ID terkuat yang didukung dari signatures. Urutan kekuatan bergantung pada setiap versi implementasi/platform.
    2. Verifikasi signature yang sesuai dari signatures terhadap signed data menggunakan public key. (Sekarang Anda dapat mengurai signed data dengan aman.)
    3. Verifikasi bahwa versi SDK minimum dan maksimum dalam data yang ditandatangani cocok dengan versi yang ditentukan untuk signer.
    4. Pastikan daftar ID algoritma tanda tangan yang diurutkan di digests dan signatures identik. (Tindakan ini dilakukan untuk mencegah penghapusan/penambahan tanda tangan.)
    5. Hitung ringkasan konten APK menggunakan algoritma ringkasan yang sama dengan algoritma ringkasan yang digunakan oleh algoritma tanda tangan.
    6. Verifikasi bahwa ringkasan yang dihitung identik dengan digest yang sesuai dari digests.
    7. Verifikasi bahwa SubjectPublicKeyInfo dari certificate pertama certificates identik dengan public key.
    8. Jika atribut bukti rotasi ada untuk signer, pastikan struct valid dan signer ini adalah sertifikat terakhir dalam daftar.
  4. Verifikasi berhasil jika tepat satu signer ditemukan dalam rentang platform saat ini dan langkah 3 berhasil untuk signer tersebut.

Validasi

Untuk menguji apakah perangkat Anda mendukung v3 dengan benar, jalankan pengujian CTS PkgInstallSignatureVerificationTest.java di cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.