EncryptedSharedPreferences: cos'è, API e come usarlo

Autore: IT Sectr Pubblicato: 2026-03-14 Tempo di lettura: 10 min

EncryptedSharedPreferences è un componente della libreria AndroidX Security che fornisce una crittografia trasparente dei dati salvati tramite l'API SharedPreferences. A differenza delle SharedPreferences normali, dove i dati vengono memorizzati in un file XML in chiaro, EncryptedSharedPreferences crittografa automaticamente chiavi e valori prima di scriverli su disco. Secondo Android Developers, la libreria utilizza AES-256 GCM per i valori e AES-256 SIV (RFC 5297) per le chiavi, garantendo riservatezza e integrità dei dati.

Punti Chiave

  • EncryptedSharedPreferences — un wrapper su SharedPreferences con crittografia automatica di tutti i dati salvati
  • La crittografia utilizza AES-256 GCM per i valori e AES-256 SIV per le chiavi tramite Android Keystore
  • Authenticated Encryption (AEAD) garantisce che i dati non siano stati alterati dopo la scrittura
  • Master Key è memorizzata in Android Keystore ed è protetta hardware sui dispositivi con TEE
  • L'API è completamente compatibile con SharedPreferences — la sostituzione avviene senza modificare il codice di lettura e scrittura

Cos'è EncryptedSharedPreferences?

EncryptedSharedPreferences è una classe del pacchetto androidx.security.crypto, introdotta in AndroidX Security 1.0.0 (2019). Implementa l'interfaccia SharedPreferences, ma tutte le operazioni di scrittura (putString, putInt, putBoolean, ecc.) crittografano i dati in anticipo e le operazioni di lettura li decrittografano prima di restituirli.

Il problema delle SharedPreferences normali

Le SharedPreferences standard salvano i dati in un file XML nella directory dell'app (/data/data/package/shared_prefs/). Il file non è crittografato — con accesso root al dispositivo o durante l'analisi del backup, tutti i dati vengono letti come XML in chiaro. I token di autenticazione, le chiavi API e i dati personali dell'utente diventano accessibili a un malintenzionato.

EncryptedSharedPreferences risolve questo problema a livello di libreria: i dati vengono crittografati prima di essere scritti su disco e decrittografati durante la lettura. Lo sviluppatore non deve chiamare manualmente funzioni crittografiche — l'API rimane identica alle SharedPreferences normali.

Storia e versioni

La libreria AndroidX Security v1.0.0 è stata rilasciata a dicembre 2019. EncryptedSharedPreferences ha sostituito l'approccio obsoleto della crittografia manuale tramite Cipher + SharedPreferences. La versione stabile attuale è 1.1.0-alpha06 (2024), che supporta API 19+. La libreria fa parte di Jetpack e non richiede autorizzazioni aggiuntive.

Secondo il Google Security Blog (2024), EncryptedSharedPreferences è il metodo consigliato per memorizzare impostazioni sensibili dell'app che non richiedono sincronizzazione cloud. Per scenari più complessi, si consiglia Room con crittografia SQLCipher.

Come funziona EncryptedSharedPreferences?

EncryptedSharedPreferences utilizza uno schema di crittografia a due livelli: la Master Key è memorizzata in Android Keystore e chiavi derivate vengono utilizzate per la crittografia dei dati. Questo combina la protezione del Keystore con le prestazioni della crittografia simmetrica.

Schema di crittografia: AES-256 GCM + SIV

Per i valori viene utilizzato AES-256 GCM (modalità Galois/Counter) — una modalità di crittografia autenticata (AEAD) che garantisce riservatezza e integrità dei dati. Per le chiavi (nomi dei parametri) viene applicato AES-256 SIV (RFC 5297) — crittografia deterministica necessaria per la ricerca delle chiavi senza rivelarne il contenuto.

Ogni file di EncryptedSharedPreferences contiene coppie chiave-valore crittografate. La struttura del file include: prima un'intestazione con metadati (versione, identificatore di chiave), poi un elenco di voci crittografate. Il file non è XML valido e non può essere letto da editor di testo.

MasterKey e KeyStore

La classe MasterKey è responsabile della creazione e gestione di una chiave master a 256 bit memorizzata in Android Keystore. MasterKey.Builder consente di configurare: tipo di archiviazione (Keystore o software), protezione biometrica e durata della chiave. Per impostazione predefinita, la chiave master viene generata in Android Keystore con l'algoritmo AES/GCM/NoPadding.

kotlin
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
    )
}

Configurazione della crittografia

EncryptedSharedPreferences.create accetta cinque parametri: contesto, nome file, chiave master, schema di crittografia delle chiavi e schema di crittografia dei valori. La scelta degli schemi influisce sulle prestazioni e sul livello di sicurezza.

Schemi di crittografia delle chiavi

AES256_SIV — crittografia deterministica: chiavi identiche producono sempre lo stesso testo cifrato. Questo è necessario per la ricerca delle chiavi (SharedPreferences.getX(key)). Svantaggio: un malintenzionato può determinare quali chiavi vengono utilizzate confrontando testi cifrati ripetuti. AES256_SIV2 — una versione migliorata con randomizzazione aggiuntiva.

Per i valori viene utilizzato AES256_GCM. GCM aggiunge un IV di 12 byte (vettore di inizializzazione) e un tag di autenticazione di 16 byte a ogni valore. Questo fornisce riservatezza (nessuno può leggere il valore) e autenticazione (nessuno può alterare il valore senza essere scoperto).

Protezione biometrica della chiave master

Il metodo setUserAuthenticationRequired(true) in MasterKey.Builder richiede la conferma biometrica prima di recuperare la chiave master dal Keystore. Questo aggiunge un ulteriore livello: anche se l'app è in esecuzione su un dispositivo sbloccato, un malintenzionato non può leggere EncryptedSharedPreferences senza Face ID o Touch ID.

Importante: con setUserAuthenticationRequired, la chiave master diventa indisponibile se l'utente modifica o rimuove i dati biometrici. È necessario gestire KeyPermanentlyInvalidatedException e creare una nuova chiave master con migrazione dei dati.

kotlin
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) {
        // La biometria è cambiata — è necessario ricreare la chiave
    }
}

Esempio di utilizzo in Kotlin

Vediamo un esempio completo di integrazione di EncryptedSharedPreferences in un'app Android con Kotlin. La libreria androidx.security:security-crypto viene aggiunta tramite Gradle.

Aggiunta della dipendenza

Nel file build.gradle (app), aggiungi: implementation “androidx.security:security-crypto:1.1.0-alpha06”. Per i progetti Kotlin, è necessario anche kotlin-stdlib. L'inizializzazione di MasterKey avviene una volta, di solito in Application.onCreate o tramite un contenitore DI.

Lettura e scrittura dei dati

Dopo aver creato un'istanza di EncryptedSharedPreferences, l'API non differisce dalle SharedPreferences normali. edit() restituisce un Editor, tutti i metodi (putString, getString, putBoolean, getBoolean) funzionano allo stesso modo. L'unica differenza è interna: i dati vengono crittografati in scrittura e decrittografati in lettura.

kotlin
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()
    }
}

Migrazione dalle SharedPreferences normali

Per migrare i dati esistenti dalle SharedPreferences non crittografate a EncryptedSharedPreferences, è necessario: leggere tutti i dati dal vecchio file, creare una nuova EncryptedSharedPreferences, scrivere tutti i dati ed eliminare il vecchio file. Google non fornisce un migratore integrato — lo sviluppatore lo implementa manualmente.

Confronto con SharedPreferences normali

La scelta tra SharedPreferences e EncryptedSharedPreferences dipende dal tipo di dati memorizzati. Per le impostazioni dell'interfaccia (tema, lingua, ordinamento), le SharedPreferences normali sono sufficienti. Per informazioni riservate (token, password, chiavi), EncryptedSharedPreferences è obbligatorio.

Prestazioni

EncryptedSharedPreferences è più lento di quello normale a causa delle operazioni crittografiche. La scrittura di un singolo valore stringa richiede ~5-15 ms (a seconda della dimensione dei dati e dell'accelerazione hardware AES). La lettura richiede 2-5 ms. Per la maggior parte delle app questo è impercettibile, ma per operazioni batch (migrazione, ripristino) usa apply() invece di commit().

Sicurezza

Le SharedPreferences normali non offrono alcuna protezione crittografica: il file XML può essere letto da qualsiasi processo con accesso root o tramite adb backup. EncryptedSharedPreferences crittografa i dati a livello di applicazione e la chiave master è memorizzata in Android Keystore con protezione hardware opzionale (StrongBox).

CaratteristicaSharedPreferencesEncryptedSharedPreferences
ArchiviazioneXML in chiaroFile binario crittografato
CrittografiaNessunaAES-256 GCM + SIV
Protezione chiaviNessunaAndroid Keystore + StrongBox
Prestazioni0.1-1 ms2-15 ms
RaccomandazioneImpostazioni UIToken, chiavi, PII

Quando scegliere EncryptedSharedPreferences

Usa EncryptedSharedPreferences per memorizzare: token di aggiornamento OAuth, chiavi API per servizi esterni, email o numero di telefono dell'utente e impostazioni sensibili dell'app (PIN, flag di autenticazione). EncryptedSharedPreferences non è adatto per memorizzare dati biometrici o documenti di grandi dimensioni — usa EncryptedFile o Room con SQLCipher.

La regola generale: se una perdita di dati danneggerebbe l'utente o l'azienda — usa EncryptedSharedPreferences. Se i dati sono solo estetici (tema, lingua, ordinamento) — SharedPreferences normali. Ha senso implementare EncryptedSharedPreferences dall'inizio, senza refactoring: sostituirlo in un progetto esistente richiede migrazione e gestione dei vecchi dati non crittografati.

Ricorda che EncryptedSharedPreferences non protegge i dati durante l'esecuzione dell'app — solo su disco. Se un malintenzionato ha accesso alla memoria del processo, i dati decrittografati possono essere intercettati. Usa protezione aggiuntiva: ProGuard/DexGuard per l'offuscamento.

Domande Frequenti

In cosa differisce EncryptedSharedPreferences da DataStore?

Jetpack DataStore è un'alternativa più moderna a SharedPreferences, basata su Flow e coroutine Kotlin. DataStore non crittografa i dati per impostazione predefinita, ma può essere combinato con EncryptedSharedPreferences o utilizzato con crittografia manuale tramite Proto DataStore con protocolli crittografici.

Si può usare EncryptedSharedPreferences per grandi volumi di dati?

Non raccomandato. EncryptedSharedPreferences è progettato per volumi ridotti (fino a 100-200 KB). Per dati più grandi, usa Room con SQLCipher o la crittografia dei file tramite EncryptedFile della stessa libreria AndroidX Security.

EncryptedSharedPreferences supporta la migrazione quando si aggiorna lo schema?

No, non esiste migrazione automatica dello schema. Quando si modifica la struttura dei dati, lo sviluppatore deve leggere manualmente i vecchi dati tramite il vecchio KeyGen e scriverli tramite il nuovo. Si consiglia di memorizzare la versione dello schema in un parametro separato.

Qual è il livello API minimo richiesto?

AndroidX Security 1.0.0 supporta API 19+ (Android KitKat). La versione 1.1.0-alpha06 supporta anch'essa API 19+. StrongBox richiede API 28+ e un dispositivo con supporto hardware (Google Pixel 3+, Samsung Galaxy S9+).

È sicuro memorizzare il refresh token in EncryptedSharedPreferences?

Sì, il refresh token è uno dei casi d'uso principali. Crittografia AES-256 GCM, chiave master in Keystore, protezione biometrica — un livello sufficiente per i token OAuth. Per i token di accesso a breve durata è adatto, anche se alcuni team preferiscono conservarli in memoria.

Riepilogo

  • EncryptedSharedPreferences — un wrapper SharedPreferences con crittografia automatica tramite AES-256 GCM (valori) e SIV (chiavi)
  • Master Key viene creata tramite MasterKey.Builder e memorizzata in Android Keystore con opzioni biometriche e StrongBox
  • L'API è completamente compatibile: edit, putString, getString, apply, clear — tutto come nelle SharedPreferences normali
  • Prestazioni: 2-15 ms per operazione, impercettibile all'utente negli scenari standard
  • Sicurezza: la crittografia autenticata (AEAD) impedisce sia la lettura che la manomissione dei dati
  • Migrazione dalle SharedPreferences normali richiede il trasferimento manuale dei dati tramite file vecchi e nuovi
  • Usa EncryptedSharedPreferences per token, chiavi API, password e altre impostazioni sensibili

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche