Secure Storage (stocare securizată) — un set de metode și tehnologii pentru protejarea datelor confidențiale pe dispozitiv: tokenuri, chei de criptare, informații de plată și date personale ale utilizatorilor. Conform OWASP Mobile Top 10 (2024), stocarea nesecurizată a datelor se află în primele trei riscuri critice. Implementarea corectă a stocării securizate previne scurgerile de date chiar și cu acces fizic la dispozitiv.
Principalele puncte
Secure Storage — practica de stocare a datelor confidențiale ale aplicației mobile astfel încât acestea să fie inaccesibile altor aplicații, programelor malware și atacatorului cu acces fizic la dispozitiv. Spre deosebire de stocarea obișnuită, Secure Storage utilizează criptare, izolare și protecție hardware.
Nu toate datele necesită Secure Storage: imaginile de profil sau cache-ul de știri pot fi stocate în sistemul de fișiere obișnuit. Cu toate acestea, cheile de criptare, tokenurile de autentificare, datele de plată, cheile private și șabloanele biometrice trebuie protejate. Potrivit Google Security Blog (2025), 67% dintre vulnerabilitățile din aplicațiile mobile sunt legate de stocarea secretelor în formă deschisă.
Fiecare platformă mobilă oferă propriile mecanisme Secure Storage: Android — Keystore și EncryptedSharedPreferences, iOS — Keychain și Data Protection API. Aceste mecanisme sunt integrate cu modulele hardware de securitate (TEE, Secure Enclave) și garantează că datele nu pot fi citite chiar și după jailbreak sau rootarea dispozitivului.
Alegerea corectă a metodei Secure Storage depinde de tipul datelor, scenariul de utilizare și cerințele de performanță. Înțelegerea arhitecturii fiecărui mecanism permite dezvoltatorului să ia o decizie arhitecturală corectă.
Platforma Android oferă mai multe niveluri de protecție a datelor, de la depozitul hardware de chei până la SharedPreferences criptate. Alegerea depinde de sensibilitatea datelor și cerințele de performanță.
Android Keystore — furnizor criptografic care generează și stochează chei într-un mediu de execuție izolat (TEE — Trusted Execution Environment) pe dispozitivele cu suport pentru protecție hardware. Cheile nu părăsesc niciodată TEE: operațiile criptografice sunt executate în interiorul unei zone protejate inaccesibile chiar și sistemului de operare.
Începând cu Android 9 (API 28), Keystore suportă StrongBox Keymaster — un cip de securitate dedicat cu propriul CPU, Generator de Numere Aleatoare Reale (TRNG) și memorie protejată. StrongBox este certificat conform Common Criteria EAL 4+ și reprezintă cel mai sigur nivel de stocare a cheilor pe Android. Pentru a utiliza StrongBox, trebuie să specificați explicit flagul inStrongBox() la generarea cheii.
Keystore suportă algoritmii: AES/GCM/NoPadding (256 biți), EC (secp256r1, secp384r1), RSA (2048–4096 biți) și HMAC-SHA256. Toate cheile pot fi legate de autentificarea biometrică prin setUserAuthenticationRequired(true).
EncryptedSharedPreferences — bibliotecă din pachetul AndroidX Security care criptează automat toate datele salvate prin API-ul SharedPreferences. Valorile sunt criptate cu cheia AES-256 GCM, iar cheile — cu AES-256 SIV (IV sintetic), ceea ce previne atacurile de dicționar asupra numelor cheilor.
Cheia principală de criptare este stocată în Android Keystore, asigurând protecție pe două niveluri: Keystore protejează cheia principală, EncryptedSharedPreferences protejează datele. Performanța criptării este sub 5 ms per operație de citire/scriere pentru date tipice (token, setări), ceea ce face biblioteca potrivită pentru scenariile utilizatorului.
EncryptedSharedPreferences nu este destinată volumelor mari de date (peste 5 MB) — în astfel de cazuri utilizați o bază de date criptată prin SQLCipher sau Room cu criptare.
SQLCipher — extensie SQLite care criptează întreaga bază de date pagină cu pagină utilizând AES-256-CBC. Fiecare pagină a bazei de date este criptată cu o cheie separată derivată din parola principală prin PBKDF2. SQLCipher adaugă aproximativ 5–15% suprasarcină de performanță în funcție de dimensiunea datelor.
Integrarea cu Android se realizează prin biblioteca net.zetetic:android-database-sqlcipher, care oferă un API compatibil cu SQLiteOpenHelper standard. Se recomandă stocarea parolei pentru SQLCipher în Keystore, nu în cod sau SharedPreferences.
Platforma iOS oferă Keychain Services — depozitul securizat principal, precum și Data Protection API pentru criptarea fișierelor la nivelul sistemului de operare.
Keychain — o bază de date SQLite criptată în care iOS stochează parole, chei de criptare, certificate și note. Fiecare element Keychain (SecItem) este stocat în formă criptată utilizând o cheie hardware unică pentru dispozitiv. Accesul la element este controlat prin ACL (Access Control List), care poate necesita autentificare biometrică (Face ID, Touch ID) sau codul de acces.
Keychain suportă clase de protecție (Protection Class) care determină când datele sunt disponibile: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — datele sunt disponibile doar când dispozitivul este deblocat și nu sunt transferate la copierea de rezervă. Această clasă este recomandată pentru majoritatea scenariilor de stocare a tokenurilor de autentificare.
Pe iOS 15+ este disponibil Security framework cu suport pentru chei hardware prin Secure Enclave — un procesor dedicat Apple care procesează operațiile criptografice și stochează cheile private în memorie izolată. Secure Enclave suportă algoritmii ECDSA (secp256r1) și ECDH pentru generarea cheilor care nu pot fi extrase din cip.
Data Protection — mecanism iOS care criptează fiecare fișier la nivelul sistemului de fișiere (APFS) utilizând o cheie legată de codul de acces al dispozitivului. Dezvoltatorul specifică nivelul de protecție prin atributul NSFileProtectionType la crearea fișierului: NSFileProtectionComplete — fișierul este disponibil doar când dispozitivul este deblocat.
Data Protection funcționează automat pe toate dispozitivele cu iOS 5+ dacă este setat un cod de acces. Criptarea se realizează la nivel hardware prin Dedicated AES Engine al procesorului Apple, asigurând performanță ridicată — întârzierea criptării este practic imperceptibilă pentru utilizator. Pentru a activa protecția în aplicație, este suficient să setați atributul de protecție la crearea fișierului prin FileManager.
Data Protection nu înlocuiește Keychain pentru stocarea cheilor — este utilizată pentru criptarea fișierelor, bazelor de date Core Data și a altor volume mari de date. Combinația Keychain (pentru chei) și Data Protection (pentru fișiere) asigură ciclul complet de stocare securizată pe iOS.
Să analizăm exemple practice de Secure Storage utilizând API-urile integrate Android și iOS.
Exemplul arată inițializarea EncryptedSharedPreferences cu cheia principală din Android Keystore. Toate operațiile ulterioare de citire și scriere sunt automat criptate și decriptate.
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val prefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
prefs.edit()
.putString("auth_token", "eyJhbGciOiJIUzI1NiJ9...")
.apply()
Exemplul demonstrează salvarea și citirea datelor din iOS Keychain utilizând Security framework. Codul folosește kSecAttrAccessibleWhenUnlockedThisDeviceOnly pentru protecție maximă.
import Security
func saveToKeychain(key: String, data: Data) {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemDelete(query as CFDictionary)
SecItemAdd(query as CFDictionary, nil)
}
func readFromKeychain(key: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(
query as CFDictionary, &result
)
return status == errSecSuccess ? result as? Data : nil
}
Exemplu de conectare la o bază de date SQLite criptată prin SQLCipher cu parola stocată în Android Keystore.
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper
class SecureDBHelper(context: Context) :
SQLiteOpenHelper(context, "secure.db", null, 1) {
private val password = getKeyFromKeystore()
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE tokens (id INTEGER PRIMARY KEY, value TEXT)")
}
override fun onUpgrade(
db: SQLiteDatabase, oldVersion: Int, newVersion: Int
) {
onCreate(db)
}
}
// Utilizare: introduceți parola la deschidere
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)
Utilizarea corectă a Secure Storage necesită respectarea câtorva principii fundamentale care previn greșelile tipice ale dezvoltatorilor.
Stabiliți clasificarea datelor: care date necesită protecție hardware (Keystore / Secure Enclave), care — criptare la nivelul sistemului de operare (EncryptedSharedPreferences / Data Protection) și care pot fi stocate în sistemul de fișiere obișnuit. Tokenurile de autentificare, cheile private și datele de plată — doar nivel hardware. Setările utilizatorului (temă, limbă) — este suficient EncryptedSharedPreferences. Datele de sesiune (cache-uri temporare) pot fi stocate în memorie sau directorul temporar.
Nu stocați niciodată secrete în cod: șirurile cu chei API, parole sau fraze seed în codul sursă — cea mai gravă eroare de securitate. Orice reverse engineering va dezvălui imediat aceste date. Utilizați Keystore pentru chei, iar pentru configurare — încărcare de pe server la pornirea aplicației (remote config).
Utilizați legătura biometrică pentru operații critice: Android Keystore și iOS Keychain suportă legarea cheilor de autentificarea biometrică. La fiecare accesare a cheii, sistemul solicită Face ID, Touch ID sau biometria Android (BiometricPrompt). Aceasta garantează că, chiar și cu control complet asupra dispozitivului, atacatorul nu poate utiliza datele stocate fără proprietar.
Testați protecția: utilizați instrumente de analiză a securității — MobSF (Mobile Security Framework) pentru analiză statică, objection pentru testare runtime și Frida pentru ocolirea protecției. Verificați că datele sunt inaccesibile după root sau jailbreak. Android permite verificarea prezenței root-ului prin SafetyNet Attestation sau Play Integrity API, iOS — prin verificarea integrității Secure Enclave.
Actualizați regulat bibliotecile criptografice: vulnerabilitățile în bibliotecile de criptare sunt descoperite regulat. Urmăriți CVE-urile pentru AndroidX Security, SQLCipher și wrapper-ele Keychain. Implementați un sistem de notificări automate pentru versiuni noi prin Dependabot sau Renovate.
Potrivit Apple Security Research (2025), implementarea corectă a Secure Storage previne 96% dintre atacurile vizând furtul datelor de pe dispozitiv. Restul de 4% — atacuri cu acces fizic și exploit-uri de zi zero, împotriva cărora este eficientă legătura biometrică.
Întrebări frecvente
iOS Keychain — bază de date criptată pentru stocarea parolelor, cheilor și certificatelor cu control al accesului prin ACL. Android Keystore — furnizor criptografic care generează și stochează chei într-un mediu izolat (TEE/StrongBox) și nu permite extragerea cheii private.
EncryptedSharedPreferences utilizează AES-256 GCM pentru criptarea valorilor și AES-256 SIV pentru criptarea cheilor. Cheia principală este stocată în Android Keystore, asigurând protecție pe două niveluri. În plus, se utilizează HMAC-SHA256 pentru verificarea integrității.
Da, HTTPS protejează datele doar în canalul de transmisie. Pe dispozitiv, datele sunt stocate în formă deschisă după decriptare. Dacă atacatorul obține acces fizic la dispozitiv sau instalează malware, HTTPS nu va proteja datele stocate. Criptați întotdeauna datele la nivelul stocării.
Utilizați Android Keystore cu flagul setUnlockedDeviceRequired(true), care blochează accesul la chei pe dispozitivele rootate. În plus, verificați integritatea prin Play Integrity API și, la abaterea de la valorile de referință, ștergeți toate secretele din depozit.
Nu, UserDefaults stochează datele în formă deschisă într-un fișier plist în interiorul sandbox-ului. Orice aplicație cu instrumente de reverse engineering (prin copie de rezervă sau jailbreak) poate citi tokenurile. Doar Keychain — singurul loc sigur pentru stocarea secretelor pe iOS.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și