EncryptedSharedPreferences — ay isang component ng AndroidX Security library na nagbibigay ng transparent na encryption ng data na nai-save sa pamamagitan ng SharedPreferences API. Hindi tulad ng ordinaryong SharedPreferences, kung saan ang data ay naka-imbak sa isang bukas na XML file, awtomatikong ina-encrypt ng EncryptedSharedPreferences ang mga key at value bago isulat sa disk. Ayon sa Android Developers, ang library ay gumagamit ng AES-256 GCM para sa mga value at AES-256 SIV (RFC 5297) para sa mga key, na tinitiyak ang confidentiality at integrity ng data.
Mga Pangunahing Punto
EncryptedSharedPreferences — ay isang klase mula sa package na androidx.security.crypto, na ipinakilala sa AndroidX Security 1.0.0 (2019). Ipinapatupad nito ang SharedPreferences interface, ngunit ang lahat ng write operations (putString, putInt, putBoolean atbp.) ay nag-e-encrypt ng data nang maaga, at ang read operations ay nagde-decrypt ng mga ito bago ibalik.
Ang karaniwang SharedPreferences ay nagse-save ng data sa isang XML file sa direktoryo ng application (/data/data/package/shared_prefs/). Ang file ay hindi naka-encrypt — sa root access sa device o sa backup analysis, lahat ng data ay nababasa bilang ordinaryong XML. Ang mga authentication token, API key, personal na data ng user ay nagiging accessible sa attacker.
EncryptedSharedPreferences ay nilulutas ang problemang ito sa antas ng library: ang data ay naka-encrypt bago isulat sa disk at na-decrypt kapag binabasa. Hindi kailangan ng developer na manu-manong tumawag ng cryptographic functions — ang API ay nananatiling katulad ng ordinaryong SharedPreferences.
Ang AndroidX Security library v1.0.0 ay inilabas noong Disyembre 2019. Pinalitan ng EncryptedSharedPreferences ang lumang approach na may manual encryption sa pamamagitan ng Cipher + SharedPreferences. Ang kasalukuyang stable na bersyon ay 1.1.0-alpha06 (2024), na sumusuporta sa API 19+. Ang library ay bahagi ng Jetpack at hindi nangangailangan ng mga karagdagang pahintulot.
Ayon sa Google Security Blog (2024), ang EncryptedSharedPreferences ay ang inirerekomendang paraan para sa pag-iimbak ng mga kumpidensyal na setting ng application na hindi nangangailangan ng sync sa cloud. Para sa mas kumplikadong mga scenario, ang Room na may encryption sa pamamagitan ng SQLCipher ay inirerekomenda.
EncryptedSharedPreferences ay gumagamit ng two-level encryption scheme: ang master key (Master Key) ay naka-imbak sa Android Keystore, at para sa encryption ng data ay ginagamit ang mga derived key. Ito ay kombinasyon ng proteksyon ng Keystore at performance ng symmetric encryption.
Para sa mga value ginagamit ang AES-256 GCM (Galois/Counter Mode) — authenticated encryption mode (AEAD), na tinitiyak ang confidentiality at integrity ng data. Para sa mga key (pangalan ng parameter) ay inaapply ang AES-256 SIV (RFC 5297) — deterministic encryption, na kinakailangan para sa paghahanap ayon sa key nang hindi inilalantad ang nilalaman nito.
Ang bawat file ng EncryptedSharedPreferences ay naglalaman ng naka-encrypt na key-value pairs. Structure ng file: una ang header na may metadata (bersyon, key identifier), pagkatapos ay listahan ng mga naka-encrypt na entry. Ang file ay hindi valid na XML at hindi nababasa ng mga text editor.
Ang klase na MasterKey ay responsable para sa paggawa at pamamahala ng 256-bit master key na naka-imbak sa Android Keystore. Ang MasterKey.Builder ay nagpapahintulot ng configuration: uri ng storage (Keystore o software), biometric protection, buhay ng key. Bilang default, ang master key ay nabuo sa Android Keystore na may AES/GCM/NoPadding algorithm.
import androidx.security.crypto.MasterKey
import androidx.security.crypto.EncryptedSharedPreferences
fun getEncryptedPrefs() {
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.AES256_GCM_SPEC)
.build()
val prefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
EncryptedSharedPreferences.create ay tumatanggap ng limang parameter: context, filename, master key, encryption scheme para sa mga key at encryption scheme para sa mga value. Ang pagpili ng mga scheme ay nakakaapekto sa performance at antas ng proteksyon.
AES256_SIV — deterministic encryption: ang magkaparehong key ay palaging nagbibigay ng parehong naka-encrypt na text. Ito ay kinakailangan para sa paghahanap ayon sa key (SharedPreferences.getX(key)). Disadvantage: maaaring matukoy ng attacker kung aling mga key ang ginagamit mula sa mga paulit-ulit na ciphertext. AES256_SIV2 — pinahusay na bersyon na may karagdagang randomization.
Para sa mga value ginagamit ang AES256_GCM. Ang GCM ay nagdaragdag ng 12-byte IV (initialization vector) at 16-byte authentication tag sa bawat value. Ito ay tinitiyak ang confidentiality (walang makakabasa ng value) at authentication (walang makakapagbago ng value nang hindi nakikita).
Ang method na setUserAuthenticationRequired(true) sa MasterKey.Builder ay nangangailangan ng biometric confirmation bago makuha ang master key mula sa Keystore. Ito ay nagdaragdag ng karagdagang layer: kahit na ang application ay tumatakbo sa isang naka-unlock na device, hindi mababasa ng attacker ang EncryptedSharedPreferences nang walang Face ID o Touch ID.
Mahalaga: sa setUserAuthenticationRequired, ang master key ay nagiging hindi available kung binago o tinanggal ng user ang biometrics. Dapat i-handle ang KeyPermanentlyInvalidatedException at gumawa ng bagong master key na may data migration.
fun createBiometricKey(): MasterKey {
return MasterKey.Builder(context)
.setKeyScheme(MasterKey.AES256_GCM_SPEC)
.setUserAuthenticationRequired(true)
.setRequestStrongBoxBacked(true)
.build()
}
fun writeSecureToken(token: String) {
try {
prefs.edit().putString("auth_token", token).apply()
} catch (e: KeyPermanentlyInvalidatedException) {
// Nagbago ang biometrics — kailangang muling likhain ang key
}
}
Tingnan natin ang isang kumpletong halimbawa ng integration ng EncryptedSharedPreferences sa isang Android application sa Kotlin. Ang library na androidx.security:security-crypto ay idinaragdag sa pamamagitan ng Gradle.
Sa file na build.gradle (app) idagdag: implementation “androidx.security:security-crypto:1.1.0-alpha06”. Para sa mga Kotlin project, kinakailangan din ang kotlin-stdlib. Ang initialization ng MasterKey ay ginagawa nang isang beses, karaniwang sa Application.onCreate o sa pamamagitan ng DI container.
Pagkatapos gumawa ng instance ng EncryptedSharedPreferences, ang API ay hindi naiiba sa ordinaryong SharedPreferences. Ang edit() ay nagbabalik ng Editor, lahat ng method (putString, getString, putBoolean, getBoolean) ay gumagana nang pareho. Ang pagkakaiba ay nasa loob lamang: ang data ay naka-encrypt kapag nagsusulat at na-decrypt kapag nagbabasa.
class AuthRepository(context: Context) {
private val prefs = createEncryptedPrefs(context)
fun saveCredentials(login: String, password: String) {
prefs.edit()
.putString("login", login)
.putString("password", password)
.apply()
}
fun getToken(): String? {
return prefs.getString("auth_token", null)
}
fun clearAll() {
prefs.edit().clear().apply()
}
}
Para sa migration ng umiiral na data mula sa hindi protektadong SharedPreferences patungo sa EncryptedSharedPreferences ay kinakailangan: basahin ang lahat ng data mula sa lumang file, gumawa ng bagong EncryptedSharedPreferences, isulat ang lahat ng data, tanggalin ang lumang file. Ang Google ay hindi nagbibigay ng built-in na migrator — ang developer ay nagpapatupad nito mismo.
Ang pagpili sa pagitan ng SharedPreferences at EncryptedSharedPreferences ay depende sa uri ng data na iniimbak. Para sa mga setting ng interface (tema, wika, sorting) sapat na ang ordinaryong SharedPreferences. Para sa kumpidensyal na impormasyon (token, password, key) ang EncryptedSharedPreferences ay kinakailangan.
Ang EncryptedSharedPreferences ay mas mabagal kaysa sa ordinaryo dahil sa cryptographic operations. Ang pagsulat ng isang string value ay tumatagal ng ~5-15 ms (depende sa laki ng data at hardware acceleration ng AES). Pagbasa — 2-5 ms. Para sa karamihan ng mga application, ito ay hindi napapansin, ngunit sa mga batch operation (migration, restoration) mas mainam na gamitin ang apply() sa halip na commit().
Ang ordinaryong SharedPreferences ay hindi nagbibigay ng anumang cryptographic protection: ang XML file ay nababasa ng anumang proseso na may root access o sa pamamagitan ng adb backup. Ang EncryptedSharedPreferences ay nag-e-encrypt ng data sa antas ng application, at ang master key ay naka-imbak sa Android Keystore na may posibilidad ng hardware protection (StrongBox).
| Katangian | SharedPreferences | EncryptedSharedPreferences |
|---|---|---|
| Storage | Bukas na XML | Naka-encrypt na binary file |
| Encryption | Wala | AES-256 GCM + SIV |
| Proteksyon ng key | Wala | Android Keystore + StrongBox |
| Performance | 0.1-1 ms | 2-15 ms |
| Rekomendasyon | Setting ng UI | Token, key, PII |
Gamitin ang EncryptedSharedPreferences para sa pag-iimbak ng: OAuth refresh token, API key para sa mga external na serbisyo, email o numero ng telepono ng user, kumpidensyal na setting ng application (PIN, authentication flags). Para sa pag-iimbak ng biometric data o malalaking dokumento, hindi angkop ang EncryptedSharedPreferences — gamitin ang EncryptedFile o Room na may SQLCipher.
Pangkalahatang tuntunin: kung ang pagtagas ng data ay makakasama sa user o negosyo — gamitin ang EncryptedSharedPreferences. Kung ang data ay kosmetiko lamang (tema, wika, sorting) — ordinaryong SharedPreferences. Makatuwirang ipatupad ang EncryptedSharedPreferences kaagad, nang walang refactoring: ang pagpapalit sa isang umiiral na proyekto ay nangangailangan ng migration at pagproseso ng lumang hindi naka-encrypt na data.
Tandaan na ang EncryptedSharedPreferences ay nagpoprotekta lamang ng data sa disk — hindi habang tumatakbo ang application. Kung ang attacker ay may access sa memory ng proseso, ang na-decrypt na data ay maaaring maharang. Gumamit ng karagdagang proteksyon: ProGuard/DexGuard para sa code obfuscation.
Mga Madalas Itanong
Jetpack DataStore — ay isang mas modernong alternatibo sa SharedPreferences, batay sa Flow at Kotlin coroutines. Ang DataStore ay hindi nag-e-encrypt ng data bilang default, ngunit maaaring isama sa EncryptedSharedPreferences o gamitin nang may manual encryption sa pamamagitan ng Proto DataStore na may cryptographic protocols.
Hindi inirerekomenda. Ang EncryptedSharedPreferences ay dinisenyo para sa maliliit na volume (hanggang 100-200 KB). Para sa malalaking data, gamitin ang Room na may SQLCipher o file encryption sa pamamagitan ng EncryptedFile mula sa parehong AndroidX Security library.
Hindi, awtomatikong schema migration ay wala. Sa pagbabago ng structure ng data, dapat manu-manong basahin ng developer ang lumang data sa pamamagitan ng lumang KeyGen at isulat ito sa pamamagitan ng bago. Inirerekomenda na iimbak ang bersyon ng schema sa isang hiwalay na parameter.
AndroidX Security 1.0.0 ay sumusuporta sa API 19+ (Android KitKat). Ang bersyon 1.1.0-alpha06 ay sumusuporta rin sa API 19+. Para sa StrongBox, kinakailangan ang API 28+ at isang device na may hardware support (Google Pixel 3+, Samsung Galaxy S9+).
Oo, ang refresh token — ay isa sa mga pangunahing gamit. AES-256 GCM encryption, master key sa Keystore, biometric protection — sapat na antas para sa OAuth tokens. Para sa access token na may maikling buhay, angkop din ito, bagaman mas gusto ng ilang team na iimbak ito sa memory.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din