Sparround

Secure storage: Keystore, EncryptedSharedPreferences

Android Keystore — kriptoqrafik açarların hardware ilə qorunan anbarı: açar materialı tətbiq prosesinə heç vaxt daxil olmur, əməliyyatlar (imza, şifrələmə) təhlükəsiz mühitdə (TEE və ya StrongBox çipi) icra olunur. Açar çıxarıla bilməz (non-exportable) — root olunmuş cihazda belə açarın özünü oğurlamaq mümkün deyil.

Açar imkanları:

  • setUserAuthenticationRequired(true) — açardan istifadə biometrika/PIN tələb edir
  • setInvalidatedByBiometricEnrollment(true) — yeni barmaq izi əlavə olunanda açar ləğv olunur
  • StrongBox (dəstəkləyən cihazlarda) — ayrıca secure element çipi

Praktik istifadə qatı: EncryptedSharedPreferences / EncryptedFile (Jetpack Security) — Keystore-dakı master açarla AES-256 şifrələmə; açar-dəyər interfeysi adi SharedPreferences kimidir.

Nəyi harada saxlamalı: access/refresh token — şifrələnmiş storage; PIN — heç vaxt açıq, yalnız salt-lı hash və ya server yoxlaması; tam kart nömrəsi (PAN) və CVV — lokalda heç vaxt.

kotlin
class SecureTokenStore(context: Context) {

    private val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)   // açar Keystore-da
        .build()

    private val prefs = EncryptedSharedPreferences.create(
        context,
        "secure_tokens",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    fun saveRefreshToken(token: String) =
        prefs.edit().putString("refresh_token", token).apply()

    fun refreshToken(): String? = prefs.getString("refresh_token", null)

    fun clear() = prefs.edit().clear().apply()   // logout-da MÜTLƏQ
}

EncryptedSharedPreferences ilə token saxlanması

Müsahibə tələləri: (1) "Token-i BuildConfig/strings.xml-də saxlasaq?" — APK decompile olunur, hər ikisi açıq mətndir; (2) "SharedPreferences onsuz da sandbox-dadır, bəs nə problem?" — root, backup extraction və digər vektorlarla oxuna bilir; sandbox təhlükəsizlik qatıdır, şifrələmə deyil; (3) allowBackup="false" və ya dataExtractionRules olmadan şifrələnməmiş fayllar buluda gedə bilər. Jetpack Security kitabxanasının deprecated statusu soruşula bilər — konsepsiya (Keystore master key + AES) dəyişməz qalır.

🛠 Tapşırıq

Token saxlama məşqi:

  • Bir dəyəri adi SharedPreferences-də saxla, sonra adb shell run-as <package> cat shared_prefs/*.xml ilə açıq mətndə oxu.
  • Eyni dəyəri EncryptedSharedPreferences ilə saxla və faylın oxunmaz olduğunu təsdiqlə.
  • Manifest-də allowBackup-ı yoxla və həssas faylları backup-dan çıxaracaq qaydanı yaz.

Bitdi sayılır: "nəyi harada saxlayırsan" cədvəlini öz layihən üçün doldura bilirsənsə.

📚 Mənbələr və sənədlər