Mobil uygulamalarda kullanıcı oturum token'ları, API anahtarları veya hassas kullanıcı verilerini depolamak güvenlik açısından kritik bir konudur. Pek çok geliştirici, varsayılan SharedPreferences (Android) veya UserDefaults (iOS) kullanır ancak bu yöntemler şifresiz ve köklenmiş/kırık cihazlarda kolayca okunabilir. Bu yazıda, platforma özel güvenli depolama çözümleri olan EncryptedSharedPreferences (Android) ve iOS Keychain kullanımını pratik adımlarla ele alıyor, sık yapılan hataları ve kontrol listesini sunuyoruz.
Neden Güvenli Depolama Kullanmalısınız?
SharedPreferences ve UserDefaults, verileri plaintext olarak cihazın dosya sisteminde saklar. Köklenmiş Android veya jailbreak yapılmış iOS cihazlarda bu dosyalara erişmek, bir saldırganın tüm token veya API anahtarlarını çalmasına olanak tanır. OAuth 2.0 gibi yöntemlerle alınan access token ve refresh token gibi hassas veriler mutlaka şifrelenmiş bir ortamda saklanmalıdır. Konu hakkında daha ayrıntılı bilgi için API Key vs OAuth 2.0: REST API Güvenliği İçin Hangi Kimlik Doğrulama Yöntemi Daha Güvenli? yazımıza göz atabilirsiniz.
Android: EncryptedSharedPreferences
Android Jetpack’in Security Crypto kütüphanesi, EncryptedSharedPreferences sınıfını sunar. Bu yapı, tüm anahtar-değer çiftlerini AES-256 ile şifreler ve anahtar yönetimi için Android Keystore’u kullanır.
Kurulum ve Kullanım Adımları
- Bağımlılığı ekleyin:
build.gradledosyanızaimplementation 'androidx.security:security-crypto:1.1.0-alpha06'satırını ekleyin. - Master Key oluşturun:
MasterKeysınıfını Android Keystore ile oluşturun. - EncryptedSharedPreferences başlatın:
EncryptedSharedPreferences.create()ile şifrelenmiş paylaşımlı tercihleri alın. - Veri yazma/okuma: Normal
SharedPreferencesgibiedit()vegetString()kullanın. Veriler otomatik olarak şifrelenip çözülür.
Örnek kod parçacığı:
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
SharedPreferences encryptedPrefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
encryptedPrefs.edit().putString("access_token", token).apply();
String token = encryptedPrefs.getString("access_token", null);
Dikkat: EncryptedSharedPreferences performans açısından normal SharedPreferences’a göre daha yavaştır, bu nedenle sık okunan basit ayarlar için değil, yalnızca hassas veriler için kullanın.
iOS: Keychain (Anahtarlık)
iOS’ta güvenli veri depolama için Keychain Services kullanılır. Bu API, verileri donanım destekli şifreleme ile saklar ve uygulamalar arası erişimi kontrol eder. Swift’te SecItemAdd, SecItemCopyMatching ve SecItemDelete fonksiyonlarıyla doğrudan kullanılabilir, ancak daha kolay bir wrapper olan KeychainAccess kütüphanesi yaygındır.
Swift ile Adım Adım Keychain Kullanımı
- KeychainAccess kütüphanesini ekleyin: Swift Package Manager veya CocoaPods ile
pod 'KeychainAccess'ekleyin. - Keychain örneği oluşturun:
let keychain = Keychain(service: "com.yourapp.token"). - Veri saklama:
keychain["access_token"] = tokenile otomatik olarak şifrelenmiş şekilde saklanır. - Veri okuma:
let token = keychain["access_token"]. - Veri silme:
keychain["access_token"] = nil.
Keychain ayrıca erişim kontrolü (Access Control) sunar: Touch ID/Face ID gerektirecek şekilde yapılandırabilirsiniz.
let keychain = Keychain(service: "com.yourapp.token")
.accessibility(.whenUnlockedThisDeviceOnly, authenticationPolicy: .biometryCurrentSet)
keychain["secret_pin"] = "1234"
iOS Keychain, Android EncryptedSharedPreferences’a göre daha güçlüdür çünkü donanım tabanlı şifreleme ve biyometrik kilit desteği sunar. Ancak kullanımı biraz daha karmaşıktır. Her iki platform için de geçerli olan bir framework seçmek isterseniz, SwiftUI vs Jetpack Compose karşılaştırmamızda olduğu gibi, platformlar arası çözümler (örn. React Native, Flutter) için yerel modüller yazmanız gerekebilir.
Pratik Uygulama Kontrol Listesi
Güvenli veri depolama entegrasyonunuzda aşağıdaki maddeleri kontrol edin:
- Platforma özel API kullanıldı mı? Android’de EncryptedSharedPreferences, iOS’ta Keychain. Root/Jailbreak tespiti ekleyip mekanizmayı devre dışı bırakabilirsiniz.
- Yedekleme hariç tutuldu mu? Android’de
android:backupAgentayarlarıyla veya iOS’ta Keychain ayarlarındakSecAttrSynchronizableseçeneğini doğru yapılandırın. - Anahtar yönetimi güvenli mi? Android’de MasterKey için
KeyScheme.AES256_GCMkullanın, asla sabit bir parola koymayın. - Access token ve refresh token ayrı mı saklanıyor? Token türüne göre farklı keychain/pref alanları kullanın.
- Biyometrik kilit isteniyor mu? Yüksek güvenlik gerekiyorsa iOS’ta
.biometryCurrentSetveya Android’deBiometricPromptile entegre edin. - Loglama yapılırken hassas veri yazdırılmıyor mu?
print(token)gibi hata ayıklama satırlarını kaldırın veya sadece debug build’de çalıştırın. - Çıkış yaparken veriler temizleniyor mu? Logout işleminde EncryptedSharedPreferences’da
clear()veya Keychain’de ilgili öğeleri silin.
Sık Yapılan Hatalar ve Kaçınılması Gerekenler
- Plaintext SharedPreferences kullanımı: Asla token, şifre veya kredi kartı bilgisi gibi verileri
SharedPreferencesveyaUserDefaultsile saklamayın. - Sabit şifreleme anahtarı kullanmak: Android’de
MasterKey.Builderile Keystore üzerinden oluşturulan anahtarı tercih edin, uygulama içinde sabit byte array kullanmayın. - Keychain’de
kSecAttrAccessibleayarını yanlış yapmak: Cihaz kilitliyken erişilebilmesi içinkSecAttrAccessibleWhenUnlockedThisDeviceOnlykullanın. - iOS’ta Keychain verilerini iCloud ile senkronize etmek: Eğer çoklu cihaz desteği istemiyorsanız
kSecAttrSynchronizabledeğerinifalseyapın. - Hassas verileri intent extras veya userInfo dictionary içinde geçirmek: Verileri Activity/ViewController arasında iletirken geçici bir süre için bile olsa bu yapıları kullanmayın; bunun yerine direkt olarak güvenli depodan okuyun.
Platformlar Arası Not: React Native ve Flutter
React Native projelerinde react-native-keychain ve react-native-encrypted-storage kütüphaneleri, Flutter projelerinde ise flutter_secure_storage paketi, Android EncryptedSharedPreferences ve iOS Keychain’i arka planda kullanır. Bu kütüphaneleri tercih ederken aktif bakım ve güncelleme durumlarını kontrol edin.
Güvenli veri saklama, mobil uygulama güvenliğinin temel taşlarından biridir. Yukarıdaki adımları izleyerek token, API anahtarı gibi değerleri güvence altına alabilir ve kullanıcı verilerini koruyabilirsiniz. Unutmayın, hiçbir çözüm %100 güvenli değildir; ancak bu yöntemler saldırganları caydırmak için gerekli katmanı sağlar.
Sık Sorulan Sorular
SharedPreferences ve UserDefaults neden güvenli değil?
Bu yöntemler verileri şifresiz olarak cihazın dosya sisteminde saklar. Köklenmiş veya jailbreak yapılmış cihazlarda herhangi bir uygulama bu dosyalara erişerek token, şifre gibi hassas bilgileri okuyabilir.
EncryptedSharedPreferences ve iOS Keychain arasındaki temel fark nedir?
EncryptedSharedPreferences Android’de Jetpack Security ile AES-256 şifreleme kullanırken, iOS Keychain donanım destekli şifreleme ve biyometrik kilit (Face ID/Touch ID) desteği sunar. Keychain genellikle daha güvenli kabul edilir.
Cross-platform frameworklerde (React Native, Flutter) güvenli depolama nasıl yapılır?
React Native için react-native-keychain veya react-native-encrypted-storage, Flutter için flutter_secure_storage kütüphanesi kullanılır. Bu kütüphaneler altta yatan platform API'lerini (EncryptedSharedPreferences ve Keychain) kullanır.
Token'ları saklarken nelere dikkat etmeliyim?
Token’ları platformun güvenli API’leriyle (EncryptedSharedPreferences/Keychain) saklayın. Ayrıca logout işlemi sırasında temizleyin, log’lara yazdırmayın, ve intent/ bundle içinde taşımayın.
iOS Keychain’deki verilerin iCloud yedeklenmesini nasıl engellerim?
Keychain öğesini oluştururken kSecAttrSynchronizable değerini false (kCFBooleanFalse) olarak ayarlayın. Böylece veriler iCloud yerine yalnızca cihazda saklanır.






