Code Signing (kod imzalama), yürütülebilir dosyalar için geliştiricinin kimliğini ve uygulama bütünlüğünü garanti eden bir dijital imza mekanizmasıdır. Android'de, her APK dosyası bir cihaza kurulmadan veya Google Play'de yayınlanmadan önce bir sertifika ile imzalanmalıdır. Google, 2024'e göre Android, JAR tabanlı v1'den akış kurulumu için v4'e kadar dört nesil imzalama şemasını desteklemektedir.
Önemli Noktalar
Code Signing, geliştiricinin yürütülebilir kodu dijital sertifikasıyla imzaladığı bir kriptografik süreçtir. İmza, asimetrik şifreleme kullanılarak oluşturulur: geliştiricinin özel anahtarı dijital bir imza oluşturur ve genel anahtar sertifikaya gömülür. Herkes genel anahtarı kullanarak imzayı doğrulayabilir, ancak imzayı bozmadan kodu değiştirmek imkansızdır.
Mobil geliştirmede, kod imzalama üç işlevi yerine getirir. Birincisi — kimlik doğrulama: kullanıcı ve platform uygulama geliştiricisini tanımlayabilir. İkincisi — bütünlük: imzalamadan sonra APK'da yapılacak herhangi bir değişiklik imzayı geçersiz kılar. Üçüncüsü — güvenilir güncelleme: platform, bir uygulamanın yalnızca yüklü sürümle aynı sertifikayla imzalanmış APK'lerle güncellenmesine izin verir.
Android uygulamalarının dijital imzası yasal öneme sahiptir. Rusya mevzuatına (63-FZ) ve Avrupa eIDAS'a göre, nitelikli elektronik imza, el yazısı imzaya eşdeğerdir. Bununla birlikte, bir APK'yı kendi kendine imzalanmış bir sertifikayla (Android'de yaygın uygulama) imzalamak nitelikli değildir — bütünlüğü onaylar, ancak yasal açıdan geliştiricinin kimliğini onaylamaz.
Android, her biri önceki sürümün sorunlarını çözen ve yeni özellikler ekleyen dört APK imzalama şemasını destekler. Tüm şemalar tek bir APK'da bir arada bulunabilir — bu, eski Android sürümleriyle geriye dönük uyumluluk için gereklidir.
v1 (JAR imzalama) şeması Android 1.0'da ortaya çıktı. META-INF/MANIFEST.MF'deki girişleri kullanarak APK arşivi içindeki tek tek dosyaları imzalar. Dezavantajı: bir saldırgan APK'yı değiştirebilir (dosya ekleyebilir veya kaldırabilir) ve geri kalanına dokunmadan yalnızca değiştirilen dosyaları yeniden imzalayabilir. Bu, v1'i belirli saldırılara karşı savunmasız hale getirir. Android 7.0'da tanıtılan v2 (APK Signature Scheme), imzanın kendisi dışındaki tüm baytlar dahil olmak üzere APK dosyasının tamamını bir bütün olarak imzalar ve seçici değişiklik olasılığını ortadan kaldırır.
| Şema | Android | Özellik | Anahtar Döndürme |
|---|---|---|---|
| v1 (JAR) | 1.0+ | Dosya başına imzalama | Hayır |
| v2 | 7.0+ | Tam APK imzalama | Hayır |
| v3 | 9.0+ | İmza + döndürme | Evet |
| v4 | 11.0+ | Akış + ADB | Evet |
Android 9.0'da tanıtılan şema v3, uzun süredir devam eden bir sorunu çözer: imzalama anahtarı tehlikeye girerse veya süresi dolarsa ne yapmalı? Daha önce, imzalama anahtarını değiştirmek, uygulamanın yeni olarak ele alınması anlamına geliyordu — mevcut bir uygulamanın üzerine kurulamazdı. v3 bir döndürme mekanizması ekler: APK, eski anahtarla imzalanmış bir döndürme kanıtı (proof-of-rotation) içerebilir. Sistem zinciri doğrular ve yeni anahtarla imzalanmış uygulamanın güncellenmesine izin verir.
Keystore, uygulamaları imzalamak için özel anahtarlar ve sertifikalar içeren güvenli bir kapsayıcıdır. Android geliştirmede JKS (Java KeyStore) veya PKCS12 formatı kullanılır. Keystore, JDK'nın bir parçası olan keytool yardımcı programıyla oluşturulur. Depodaki her anahtar bir takma adla (alias) tanımlanır ve bir parolayla korunur.
Keystore'daki sertifika, genel anahtarı ve sahip bilgilerini içerir: kuruluş adı, ülke, geçerlilik süresi. Android uygulamaları için sertifika kendi kendine imzalanmış olabilir — Google bir sertifika yetkilisi (CA) gerektirmez, bu da Android'i iOS'tan ayırır. Bununla birlikte, sertifikanın geçerlilik süresi en az 25 yıl olmalıdır, çünkü uygulama aynı anahtarla güncellenecektir.
# İmzalama için yeni keystore oluşturma
keytool -genkey -v -keystore my-release.keystore \
-alias my-app-alias \
-keyalg RSA \
-keysize 2048 \
-validity 10000
# Keystore içeriğini görüntüleme
keytool -list -v -keystore my-release.keystore
Android, imzalama anahtarları için iki algoritmayı destekler: RSA ve ECDSA. 2048 bit anahtar boyutuna sahip RSA, tüm Android sürümleri tarafından desteklenen fiili standarttır. P-256 eğrisine sahip ECDSA (Eliptik Eğri Dijital İmza Algoritması), daha küçük anahtar boyutuyla aynı kriptografik gücü sağlar. Android 9.0'dan itibaren, mobil cihazlarda doğrulamada daha hızlı olduğu için ECDSA önerilir.
Android Gradle Plugin'de imzalama, modül düzeyindeki build.gradle'daki signingConfigs bloğu aracılığıyla yapılandırılır. Hata ayıklama derlemeleri için Android Studio, bilinen parolalarla otomatik olarak bir hata ayıklama keystore'u oluşturur. Yayın derlemeleri için geliştirici, keystore'unun yolunu, anahtar takma adını ve parolaları belirtir. Parolaların, sürüm kontrolünün dışında tutulan ayrı yapılandırma dosyalarında saklanması önerilir.
Modern bir uygulama, CI/CD aracılığıyla merkezi imzalama yönetimidir. Jenkins, GitLab CI veya GitHub Actions, keystore'u korumalı bir yapıt ve parolaları ortam sırları olarak saklayabilir. Bu, depo aracılığıyla anahtar sızıntısını önler ve gerektiğinde anahtar döndürmeyi basitleştirir.
// build.gradle (uygulama düzeyi) — imzalama yapılandırması
android {
signingConfigs {
release {
storeFile file("my-release.keystore")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Maksimum uyumluluk için bir APK, üç şemanın tümüyle (v1 + v2 + v3) imzalanmalıdır. Android Gradle Plugin varsayılan olarak tüm şemaları içerir. Yalnızca v2 ile imzalanmış APK'ler Android 6.0 ve altında kurulmaz. Yalnızca v1 ile APK'ler, Android 7.0+'da v2'nin bütünlük avantajlarını elde edemez. Tüm şemaların dahil edilmesi APK boyutunu %1-2'den fazla artırmaz ve herhangi bir cihazla uyumluluk sağlar.
Play App Signing, uygulama imzalama anahtarlarını merkezi olarak yöneten bir Google Play hizmetidir. Geliştirici, Google Play Console'a bir yükleme anahtarıyla (upload key) imzalanmış bir APK yükler ve Google Play, kullanıcılara teslim etmeden önce onu bir dağıtım anahtarıyla (distribution key) yeniden imzalar. Bu, dağıtım anahtarını kayıp veya tehlikeye karşı korur.
Play App Signing'in avantajları: güvenlik — dağıtım anahtarı Google'ın korumalı deposunda saklanır; döndürme — konsol aracılığıyla anahtar değişikliği talep edilebilir; kurtarma — yükleme anahtarı kaybolursa yeni bir anahtar oluşturulabilir. Dezavantajı: Play App Signing'in tanıtılmasından önce var olan uygulamalar için geçiş, yeni bir uygulama oluşturulmasını gerektirir, çünkü eski dağıtım anahtarı zaten kullanımdadır.
# Sertifika parmak izini alma (SHA-256)
keytool -list -v -keystore my-release.keystore \
-alias my-app-alias | grep "SHA256"
# apksigner ile APK imzasını doğrulama
apksigner verify --verbose app-release.apk
İmzalama anahtarı kaybolursa ve Play App Signing kullanılmıyorsa, uygulamayı güncelleme yeteneğini geri yüklemek imkansızdır — yeni bir paket adıyla yeni bir uygulama oluşturulması gerekecektir. Bu, Play App Signing kullanmanın ana nedenlerinden biridir. Google, keystore'un yedek bir kopyasının güvenli bir çevrimdışı depoda (şifrelenmiş USB sürücü, banka kasası) saklanmasını önerir.
Bir APK kurulurken Android, imza doğrulamayı birkaç aşamada gerçekleştirir. Birincisi — sertifika kontrolü: geçerlilik süresi doldu mu, biçim doğru mu. İkincisi — imza doğrulama: kriptografik imza APK içeriğiyle eşleşiyor mu. Üçüncüsü — yüklü sürümle sertifika karşılaştırması: uygulama zaten cihazda varsa, sertifika eşleşmelidir, aksi takdirde kurulum engellenir.
Doğrulama sistemi PackageManagerService'e yerleşiktir. Bir kurulum isteğini işlerken PMS, APK'dan imzayı çıkarır, android.util.PackageParser sınıfını kullanarak doğrular ve yüklü uygulamanın (varsa) saklanan imzasıyla karşılaştırır. Eşleşmezse, kullanıcı “INSTALL_FAILED_UPDATE_INCOMPATIBLE” hatasını alır. Bu mekanizma değiştirme saldırılarını önler (kötü amaçlı yazılım, meşru bir uygulamayı kendi sürümüyle değiştiremez).
Bir geliştirici, Android SDK Build Tools'taki apksigner yardımcı programını kullanarak APK imzasını bağımsız olarak doğrulayabilir. apksigner verify --verbose app.apk komutu, APK'nın hangi şemalarla imzalandığını, sertifikaların geçerli olup olmadığını ve imzaların içerikle eşleşip eşleşmediğini gösterir. Yüklü bir uygulamanın imzasının programatik olarak doğrulanması için, GET_SIGNATURES bayrağıyla PackageManager.getPackageInfo() kullanılır.
// Yüklü bir uygulamanın imzasının programatik doğrulaması
fun getAppSignature(context: Context, packageName: String): String? {
val pm = context.packageManager
val info = pm.getPackageInfo(
packageName,
PackageManager.GET_SIGNATURES
)
return info.signatures?.firstOrNull()?.toCharsString()
}
İmzalama anahtarı güvenliği, Android geliştirmenin kritik bir yönüdür. Anahtarın tehlikeye girmesi, bir saldırganın uygulamanızın güncellemelerini kendi koduyla imzalamasına olanak tanır. Temel kurallar: anahtarı asla bir depoda saklamayın, farklı uygulamalar için aynı anahtarı kullanmayın, anahtarı güvenli olmayan kanallar (e-posta, mesajlaşma uygulamaları) aracılığıyla aktarmayın.
Önerilen uygulama anahtar ayrımıdır. Her uygulama için ayrı bir anahtar ve Google Play'e yüklemek için ayrı bir anahtar (yükleme anahtarı) kullanın. Hata ayıklama derlemeleri için Android Studio, paylaşılan bir debug.keystore oluşturur — bu, yayın derlemeleri için kullanılamaz. Sertifikanın geçerlilik süresi 25-30 yıl olmalıdır (mevcut standart, Google tarafından onaylanmıştır).
| Uygulama | Öneri |
|---|---|
| Anahtar depolama | Şifrelenmiş ortam, CI/CD sırları |
| Sertifika geçerliliği | En az 25 yıl |
| Algoritma | RSA 2048+ veya ECDSA P-256 |
| Ayırma | Uygulama başına ayrı anahtar |
| Yedekleme | Keystore'un çevrimdışı kopyası |
Düzenli olarak imza zinciri bütünlüğünü kontrol edin. Anahtarlara erişimi olan çalışanlar ayrıldığında, Google Play Console aracılığıyla yükleme anahtarını güncelleyin. Uygulamanızın kullanıcı cihazlarında değiştirilmediğini doğrulamak için Google Play Integrity API gibi araçları kullanın. API, imza ve bütünlük hakkında verileri döndürür ve doğrulama için sunucuya gönderir.
Sıkça Sorulan Sorular
Code Signing, uygulamanın belirli bir geliştirici tarafından oluşturulduğunu ve imzalamadan sonra değiştirilmediğini onaylayan bir APK dosyasının dijital imzasıdır. İmza olmadan APK bir cihaza kurulmaz.
JDK'daki keytool yardımcı programını kullanın: keytool -genkey -v -keystore my-release.keystore -alias my-alias -keyalg RSA -keysize 2048 -validity 10000. Elde edilen keystore'u build.gradle'daki signingConfigs bloğunda belirtin.
Anahtar kaybolursa ve Play App Signing kullanmıyorsanız, uygulamayı güncellemek imkansız hale gelir. Google Play'de yeni bir paket adıyla yeni bir uygulama oluşturmanız gerekecektir. Anahtar kaybına karşı korunmak için Play App Signing kullanın.
v1, APK içindeki her dosyayı ayrı ayrı imzalar — bir saldırgan bir dosyayı değiştirebilir ve yalnızca onu yeniden imzalayabilir. v2, APK'nın tamamını bir bütün olarak imzalar — herhangi bir değişiklik imzayı geçersiz kılar ve daha yüksek düzeyde güvenlik sağlar.
Play App Signing, uygulama dağıtım anahtarını merkezi olarak depolayan bir Google Play hizmetidir. Geliştirici, yükleme anahtarıyla imzalanmış bir APK yükler ve Google, kullanıcılara teslim etmeden önce onu yeniden imzalayarak anahtarı kayıp veya hırsızlığa karşı korur.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun