Secure Storage nelle applicazioni mobili: cos’è, metodi e implementazione

Autore: IT Sectr Pubblicato: 2026-04-04 Tempo di lettura: 9 min

Secure Storage è un insieme di metodi e tecnologie per proteggere i dati riservati su un dispositivo: token, chiavi di crittografia, informazioni di pagamento e dati personali degli utenti. Secondo OWASP Mobile Top 10 (2024), l'archiviazione non sicura dei dati è tra i tre rischi più critici. Una corretta implementazione di Secure Storage previene le fughe di dati anche con accesso fisico al dispositivo.

Punti chiave

  • Secure Storage — un insieme di metodi di crittografia e isolamento dei dati sul dispositivo per impedire l'accesso da altre applicazioni e aggressori.
  • Android Keystore — un archivio crittografico che genera e protegge le chiavi a livello hardware (TEE).
  • iOS Keychain — un database sicuro per memorizzare segreti, crittografato a livello di sistema operativo con accesso tramite Security framework.
  • EncryptedSharedPreferences — una libreria Android Jetpack per crittografare coppie chiave-valore usando AES-256.
  • Data Protection API — un meccanismo iOS che crittografa i file in base a una classe di protezione legata allo stato di blocco del dispositivo.

Cos’è Secure Storage?

Secure Storage è la pratica di archiviare i dati riservati di un'applicazione mobile in modo che siano inaccessibili ad altre applicazioni, malware e aggressori con accesso fisico al dispositivo. A differenza dell'archiviazione normale, Secure Storage utilizza crittografia, isolamento e protezione hardware.

Non tutti i dati richiedono Secure Storage: le immagini del profilo o la cache delle notizie possono essere archiviate nel filesystem normale. Tuttavia, le chiavi di crittografia, i token di autenticazione, i dati di pagamento, le chiavi private e i modelli biometrici devono essere protetti. Secondo Google Security Blog (2025), il 67% delle vulnerabilità nelle applicazioni mobili sono legate all'archiviazione di segreti in testo semplice.

Ogni piattaforma mobile fornisce i propri meccanismi Secure Storage: Android — Keystore e EncryptedSharedPreferences, iOS — Keychain e Data Protection API. Questi meccanismi sono integrati con moduli di sicurezza hardware (TEE, Secure Enclave) e garantiscono che i dati non possano essere letti nemmeno dopo il jailbreak o il root del dispositivo.

La scelta corretta del metodo Secure Storage dipende dal tipo di dati, dallo scenario di utilizzo e dai requisiti di prestazione. Comprendere l'architettura di ciascun meccanismo consente allo sviluppatore di prendere la giusta decisione architetturale.

Secure Storage su Android

La piattaforma Android offre diversi livelli di protezione dei dati, dalla memorizzazione hardware delle chiavi alle SharedPreferences crittografate. La scelta dipende dalla sensibilità dei dati e dai requisiti di prestazione.

Android Keystore — Archiviazione hardware delle chiavi

Android Keystore è un fornitore crittografico che genera e memorizza le chiavi in un ambiente di esecuzione isolato (TEE — Trusted Execution Environment) sui dispositivi con supporto alla protezione hardware. Le chiavi non lasciano mai il TEE: le operazioni crittografiche vengono eseguite all'interno di un'area protetta inaccessibile anche al sistema operativo.

A partire da Android 9 (API 28), Keystore supporta StrongBox Keymaster — un chip di sicurezza dedicato con propria CPU, generatore di numeri casuali hardware (TRNG) e memoria protetta. StrongBox è certificato Common Criteria EAL 4+ ed è il più alto livello di sicurezza di archiviazione delle chiavi su Android. Per utilizzare StrongBox, è necessario specificare esplicitamente il flag inStrongBox() durante la generazione della chiave.

Keystore supporta gli algoritmi: AES/GCM/NoPadding (256 bit), EC (secp256r1, secp384r1), RSA (2048–4096 bit) e HMAC-SHA256. Tutte le chiavi possono essere legate all'autenticazione biometrica tramite setUserAuthenticationRequired(true).

EncryptedSharedPreferences

EncryptedSharedPreferences è una libreria del pacchetto AndroidX Security che crittografa automaticamente tutti i dati salvati tramite l'API SharedPreferences. I valori vengono crittografati con una chiave AES-256 GCM e le chiavi vengono crittografate con AES-256 SIV (IV sintetico), prevenendo attacchi di dizionario sui nomi delle chiavi.

La chiave di crittografia principale è memorizzata in Android Keystore, fornendo una protezione a due livelli: Keystore protegge la chiave master, EncryptedSharedPreferences protegge i dati. Le prestazioni di crittografia sono inferiori a 5 ms per operazione di lettura/scrittura per dati tipici (token, impostazioni), rendendo la libreria adatta agli scenari utente.

EncryptedSharedPreferences non è progettato per grandi volumi di dati (oltre 5 MB) — per questi, utilizzare un database crittografato tramite SQLCipher o Room con crittografia.

SQLCipher — Database crittografato

SQLCipher è un'estensione di SQLite che crittografa l'intero database pagina per pagina con AES-256-CBC. Ogni pagina del database viene crittografata con una chiave separata derivata dalla password master tramite PBKDF2. SQLCipher aggiunge circa il 5–15% di overhead prestazionale a seconda della dimensione dei dati.

L'integrazione con Android avviene tramite la libreria net.zetetic:android-database-sqlcipher, che fornisce un'API compatibile con SQLiteOpenHelper standard. La password per SQLCipher dovrebbe essere memorizzata in Keystore, non nel codice o in SharedPreferences.

Secure Storage su iOS

La piattaforma iOS fornisce Keychain Services come archivio sicuro principale e l'API Data Protection per la crittografia dei file a livello di sistema operativo.

Keychain Services

Keychain è un database SQLite crittografato in cui iOS memorizza password, chiavi di crittografia, certificati e note. Ogni elemento Keychain (SecItem) viene memorizzato in forma crittografata utilizzando una chiave hardware unica del dispositivo. L'accesso a un elemento è controllato tramite una ACL (Access Control List), che può richiedere l'autenticazione biometrica (Face ID, Touch ID) o un codice di accesso.

Keychain supporta classi di protezione che determinano quando i dati sono accessibili: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — i dati sono accessibili solo quando il dispositivo è sbloccato e non vengono trasferiti durante il backup. Questa classe è raccomandata per la maggior parte degli scenari di archiviazione di token di autenticazione.

Su iOS 15+, il Security framework è disponibile con supporto per chiavi hardware tramite Secure Enclave — un processore Apple dedicato che gestisce le operazioni crittografiche e memorizza le chiavi private in memoria isolata. Secure Enclave supporta gli algoritmi ECDSA (secp256r1) e ECDH per generare chiavi che non possono essere estratte dal chip.

API Data Protection

Data Protection è un meccanismo iOS che crittografa ogni file a livello di filesystem (APFS) utilizzando una chiave legata al codice di accesso del dispositivo. Lo sviluppatore specifica il livello di protezione tramite l'attributo NSFileProtectionType durante la creazione del file: NSFileProtectionComplete — il file è accessibile solo quando il dispositivo è sbloccato.

Data Protection funziona automaticamente su tutti i dispositivi con iOS 5+ se è impostato un codice di accesso. La crittografia viene eseguita a livello hardware tramite il Dedicated AES Engine del processore Apple, garantendo prestazioni elevate — la latenza di crittografia è praticamente impercettibile per l'utente. Per attivare la protezione in un'applicazione, è sufficiente impostare l'attributo di protezione durante la creazione del file tramite FileManager.

Data Protection non sostituisce Keychain per la memorizzazione delle chiavi — viene utilizzato per crittografare file, database Core Data e altri grandi volumi di dati. La combinazione di Keychain (per le chiavi) e Data Protection (per i file) fornisce un ciclo completo di archiviazione sicura su iOS.

Esempi di codice: crittografia dei dati su Android e iOS

Vediamo esempi pratici di Secure Storage utilizzando le API integrate di Android e iOS.

EncryptedSharedPreferences in Kotlin

L'esempio mostra l'inizializzazione di EncryptedSharedPreferences con una chiave master da Android Keystore. Tutte le successive operazioni di lettura e scrittura vengono automaticamente crittografate e decrittografate.

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

Keychain in Swift

L'esempio mostra il salvataggio e la lettura dei dati da iOS Keychain utilizzando Security framework. Il codice utilizza kSecAttrAccessibleWhenUnlockedThisDeviceOnly per la massima protezione.

swift
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
}

SQLCipher in Kotlin

Un esempio di connessione a un database SQLite crittografato tramite SQLCipher con password memorizzata in Android Keystore.

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

// Utilizzo: passiamo la password all'apertura
val helper = SecureDBHelper(context)
val db = helper.getWritableDatabase(password)

Raccomandazioni per l'archiviazione sicura dei dati

L'uso corretto di Secure Storage richiede di seguire diversi principi fondamentali che prevengono gli errori comuni degli sviluppatori.

Definire la classificazione dei dati: quali dati richiedono protezione hardware (Keystore / Secure Enclave), quali richiedono crittografia a livello di sistema operativo (EncryptedSharedPreferences / Data Protection) e quali possono essere archiviati nel filesystem normale. Token di autenticazione, chiavi private e dati di pagamento — solo livello hardware. Impostazioni utente (tema, lingua) — EncryptedSharedPreferences è sufficiente. Dati di sessione (cache temporanee) possono essere archiviati in memoria o in una directory temporanea.

Non memorizzare mai segreti nel codice: stringhe con chiavi API, password o frasi seed nel codice sorgente sono un grave errore di sicurezza. Qualsiasi reverse engineering esporrà immediatamente questi dati. Utilizzare Keystore per le chiavi e per la configurazione — caricamento lato server all'avvio dell'applicazione (config remota).

Utilizzare il binding biometrico per le operazioni critiche: Android Keystore e iOS Keychain supportano il legame delle chiavi all'autenticazione biometrica. Ogni volta che si accede a una chiave, il sistema richiede Face ID, Touch ID o la biometria Android (BiometricPrompt). Ciò garantisce che anche con il controllo totale del dispositivo, un aggressore non possa utilizzare i dati memorizzati senza il proprietario.

Testare la sicurezza: utilizzare strumenti di analisi della sicurezza — MobSF (Mobile Security Framework) per l'analisi statica, objection per i test runtime e Frida per bypassare la protezione. Verificare che i dati siano inaccessibili dopo il root o il jailbreak. Android consente di verificare l'accesso root tramite SafetyNet Attestation o Play Integrity API, iOS — tramite verifica dell'integrità di Secure Enclave.

Aggiornare regolarmente le librerie crittografiche: le vulnerabilità nelle librerie di crittografia vengono scoperte regolarmente. Monitorare i CVE per AndroidX Security, SQLCipher e wrapper Keychain. Implementare un sistema di notifica automatica per le nuove versioni tramite Dependabot o Renovate.

Secondo Apple Security Research (2025), una corretta implementazione di Secure Storage previene il 96% degli attacchi mirati al furto di dati dal dispositivo. Il restante 4% sono attacchi con accesso fisico e exploit zero-day, contro i quali il binding biometrico è efficace.

Domande frequenti

Qual è la differenza tra Keychain e Keystore?

iOS Keychain è un database crittografato per memorizzare password, chiavi e certificati con controllo di accesso tramite ACL. Android Keystore è un fornitore crittografico che genera e memorizza chiavi in un ambiente isolato (TEE/StrongBox) e non consente di estrarre la chiave privata.

Quale algoritmo di crittografia utilizza EncryptedSharedPreferences?

EncryptedSharedPreferences utilizza AES-256 GCM per crittografare i valori e AES-256 SIV per crittografare le chiavi. La chiave master è memorizzata in Android Keystore, fornendo una protezione a due livelli. Inoltre, HMAC-SHA256 viene utilizzato per la verifica dell'integrità.

Devo crittografare i dati già protetti da HTTPS?

Sì, HTTPS protegge i dati solo nel canale di trasmissione. Sul dispositivo, i dati vengono archiviati in testo semplice dopo la decrittografia. Se un aggressore ottiene accesso fisico al dispositivo o installa malware, HTTPS non proteggerà i dati archiviati. Crittografare sempre i dati a livello di archiviazione.

Come proteggere i dati dopo il root di Android?

Utilizzare Android Keystore con il flag setUnlockedDeviceRequired(true), che blocca l'accesso alle chiavi sui dispositivi rooted. Inoltre, verificare l'integrità tramite Play Integrity API e, se si discosta dai valori di riferimento, cancellare tutti i segreti dall'archivio.

Posso utilizzare UserDefaults per memorizzare token su iOS?

No, UserDefaults memorizza i dati in testo semplice in un file plist all'interno della sandbox. Qualsiasi applicazione con strumenti di reverse engineering (tramite backup o jailbreak) può leggere i token. Solo Keychain è il luogo sicuro per memorizzare segreti su iOS.

Riepilogo

  • Secure Storage è un componente essenziale della protezione delle applicazioni mobili, prevenendo fughe di dati con accesso fisico al dispositivo.
  • Android Keystore con StrongBox fornisce l'archiviazione hardware delle chiavi su un chip di sicurezza dedicato.
  • iOS Keychain con classi di protezione (WhenUnlockedThisDeviceOnly) è lo standard per memorizzare segreti sulla piattaforma Apple.
  • EncryptedSharedPreferences è una soluzione pronta per crittografare impostazioni e token su Android con crittografia a due livelli.
  • SQLCipher è la scelta per database crittografati con crittografia AES-256-CBC pagina per pagina.
  • Data Protection su iOS e SafetyNet/Play Integrity su Android sono livelli aggiuntivi di protezione del filesystem.
  • Classificazione corretta dei dati e binding biometrico prevengono il 96% degli attacchi ai dati memorizzati secondo Apple Security Research.

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