Keychain — Concetti chiave, architettura e come funziona

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

Keychain è un archivio sicuro di credenziali in iOS, watchOS, macOS e tvOS che gestisce password, chiavi e certificati a livello hardware. A differenza di UserDefaults, i dati in Keychain sono crittografati e isolati per sandbox dell'applicazione. Secondo Apple Developer Documentation, Keychain utilizza meccanismi Secure Enclave e crittografia hardware AES-256 per proteggere le informazioni riservate.

Punti chiave

  • Keychain — archivio di sistema iOS per password, chiavi e certificati con crittografia hardware
  • Security framework fornisce funzioni C SecItemAdd, SecItemCopyMatching e SecItemDelete per lavorare con Keychain
  • L'accesso a Keychain è limitato dal sandbox dell'app, ma è possibile l'accesso condiviso tramite keychain access groups
  • L'attributo kSecAttrAccessible definisce il livello di protezione: da Always a WhenUnlockedThisDeviceOnly
  • Keychain supporta l'archiviazione di password, chiavi simmetriche e asimmetriche, certificati X.509

Cos'è Keychain?

Keychain è un database sicuro del sistema operativo Apple progettato per l'archiviazione sicura di password, chiavi crittografiche, certificati e altri dati sensibili. Keychain è apparso per la prima volta in Mac OS 8.6 nel 1999, e su iOS — dalla prima versione dell'SDK.

Definizione e scopo

Keychain risolve un problema fondamentale dello sviluppo mobile: archiviare segreti (token, password, chiavi di crittografia) in un file system non sicuro. A differenza di UserDefaults o SQLite, i dati in Keychain sono memorizzati crittografati e vengono automaticamente crittografati quando vengono scritti su disco.

Ogni applicazione iOS opera in un sandbox isolato e ha accesso solo al proprio keychain. Tuttavia, lo sviluppatore può configurare l'accesso condiviso a Keychain tra applicazioni dello stesso sviluppatore tramite keychain access groups. L'iCloud Keychain dell'utente sincronizza inoltre i dati tra i dispositivi tramite crittografia end-to-end.

Secondo Apple Security White Paper (2025), Keychain utilizza crittografia hardware AES-256 con una chiave legata all'identificatore unico del dispositivo (UID), rendendo i dati inaccessibili quando estratti dal dispositivo.

Come funziona Keychain su iOS?

Keychain funziona come un servizio a livelli: l'applicazione accede al Security framework, che comunica con il demone securityd che gestisce il database SQLite crittografato di Keychain. Ogni record viene crittografato con una chiave separata e le chiavi stesse sono protette dal modulo hardware Secure Enclave sui dispositivi con chip A7 e successivi.

Architettura del Security framework

Il Security framework fornisce un'interfaccia C per lavorare con Keychain Services. Funzioni principali: SecItemAdd (aggiungere), SecItemCopyMatching (cercare), SecItemUpdate (aggiornare) e SecItemDelete (eliminare). Ogni operazione accetta un dizionario di attributi CFDictionaryRef che descrive il tipo di richiesta.

I dati sono classificati per classi: kSecClassGenericPassword (password arbitraria), kSecClassInternetPassword (password di servizio Internet), kSecClassCertificate (certificato), kSecClassKey (chiave crittografica) e kSecClassIdentity (coppia chiave-certificato).

Processo di salvataggio dei dati

Quando si salva una password, l'applicazione crea un dizionario con attributi: servizio, account, livello di accesso, etichetta. Il Security framework passa i dati al demone securityd, che crittografa il record con una chiave legata al dispositivo e lo memorizza nel SQLite di Keychain. Il recupero funziona in modo simile: query per attributi, ricerca, decrittazione e restituzione dei dati.

Una caratteristica importante: quando un'applicazione viene eliminata, iOS automaticamente cancella i record Keychain creati da tale applicazione (da iOS 10.3+). Quando si reinstalla l'applicazione, i dati Keychain dell'installazione precedente non sono disponibili a meno che non sia stato utilizzato iCloud Keychain.

swift
import Security

func savePassword(service: String, account: String, password: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecValueData as String: password,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Tipi di dati in Keychain

Keychain supporta cinque classi principali di dati, ciascuna con il proprio insieme di attributi e ambito di applicazione. La scelta della classe determina quali chiavi di ricerca sono disponibili e come i dati vengono crittografati.

Password e account

Le classi kSecClassGenericPassword e kSecClassInternetPassword sono progettate per memorizzare password testuali. La versione Internet memorizza inoltre i dati del server: dominio, protocollo, porta e percorso di autenticazione. GenericPassword viene utilizzato per memorizzare qualsiasi password senza vincolo al server.

Quando si salva una password Internet, è possibile specificare kSecAttrServer (dominio), kSecAttrProtocol (HTTPS, FTP, ecc.), kSecAttrPort e kSecAttrPath. Ciò consente di identificare con precisione il record durante la compilazione automatica tramite AutoFill.

Chiavi crittografiche e certificati

La classe kSecClassKey memorizza chiavi simmetriche (AES) e asimmetriche (RSA, EC). La classe kSecClassCertificate memorizza certificati X.509. La classe kSecClassIdentity combina una chiave privata e il suo certificato corrispondente in un unico record.

Per le chiavi asimmetriche, Keychain supporta attributi: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (salvare in Keychain). Per i certificati: kSecAttrLabel (nome leggibile), kSecAttrSubject (DN del proprietario), kSecAttrIssuer (DN dell'emittente).

Classe KeychainScopoTipo di dato
kSecClassGenericPasswordPassword dell'appData (NSString)
kSecClassInternetPasswordPassword del serverData + attributi server
kSecClassCertificateCertificato X.509SecCertificate
kSecClassKeyChiave crittograficaSecKey
kSecClassIdentityChiave + certificatoSecIdentity

Lavorare con Keychain tramite API

L'interfaccia principale per interagire con Keychain nel codice nativo iOS sono le funzioni del Security framework. Per Swift e Objective-C, è disponibile un'unica interfaccia C, incapsulata in funzioni convenienti.

Operazioni di base SecItemAdd e SecItemCopyMatching

La funzione SecItemAdd aggiunge un nuovo elemento a Keychain. Prende come input un dizionario con classe, dati e attributi. Restituisce lo stato errSecSuccess (0) o un codice di errore. La funzione SecItemCopyMatching esegue una ricerca per attributi e restituisce i dati trovati.

Per la ricerca si usa il flag kSecReturnData — se true, la funzione restituisce il contenuto del record. Il flag kSecMatchLimit determina il numero di risultati: kSecMatchLimitOne (uno) o kSecMatchLimitAll (tutti).

swift
func readPassword(service: String, account: String) -> Data? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account,
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    guard status == errSecSuccess else { return nil }
    return item as? Data
}

Eliminazione e aggiornamento dei record

SecItemUpdate consente di modificare attributi o dati di un record esistente. SecItemDelete elimina tutti i record corrispondenti al dizionario passato. Durante l'eliminazione, è importante specificare attributi sufficienti per non eliminare accidentalmente record altrui nel keychain condiviso.

swift
func deletePassword(service: String, account: String) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: account
    ]
    SecItemDelete(query as CFDictionary)
}

Livelli di accesso e protezione dei dati

Ogni record Keychain ha l'attributo kSecAttrAccessible, che determina quando i dati sono disponibili per la lettura. Questo è criticamente importante per la sicurezza: un livello di accesso sbagliato può rendere i dati vulnerabili o, al contrario, non disponibili quando necessario.

Costanti di accessibilità

kSecAttrAccessibleWhenUnlocked — dati disponibili solo quando il dispositivo è sbloccato. kSecAttrAccessibleAfterFirstUnlock — disponibili dopo il primo sblocco dopo il riavvio. kSecAttrAccessibleAlways — sempre disponibili (non consigliato). Il suffisso ThisDeviceOnly impedisce il trasferimento dei dati tramite backup.

Sui dispositivi con Secure Enclave, la chiave di crittografia di Keychain può essere ulteriormente protetta dalla biometria: kSecAccessControlBiometryCurrentSet o kSecAccessControlUserPresence. Questo aggiunge un requisito di Face ID o Touch ID per ogni operazione di lettura.

iCloud Keychain e sincronizzazione

iCloud Keychain sincronizza i record tra i dispositivi Apple tramite crittografia end-to-end. Apple non ha accesso ai dati decrittati. Per abilitare la sincronizzazione, aggiungere l'attributo kSecAttrSynchronizable con il valore kCFBooleanTrue.

Importante: i record sincronizzati non possono contenere l'attributo ThisDeviceOnly, poiché devono essere disponibili su altri dispositivi. Se tutti i dispositivi vengono persi, iCloud Keychain può essere ripristinato tramite un codice di ripristino o una chiave di ripristino iCloud.

Migliori pratiche per la scelta del livello di accesso

Per i token di autenticazione, utilizzare kSecAttrAccessibleWhenUnlockedThisDeviceOnly — dati disponibili solo quando il dispositivo è sbloccato e non copiati nel backup. Per i certificati che devono essere disponibili per le attività in background, utilizzare kSecAttrAccessibleAfterFirstUnlock. Non utilizzare mai kSecAttrAccessibleAlways per dati sensibili.

Si raccomanda di aggiungere sempre il suffisso ThisDeviceOnly per i dati che non richiedono sincronizzazione. Ciò impedisce la copia accidentale di segreti in iCloud o iTunes backup, dove potrebbero essere estratti con strumenti di analisi. Per i dati critici, combinare l'accessibilità con kSecAccessControlUserPresence — questo aggiunge un requisito biometrico o di codice per la decrittazione del record.

Quando si utilizza iCloud Keychain, tenere presente che i record sincronizzati sono disponibili su tutti i dispositivi dell'utente: se un attaccante ottiene l'accesso a un dispositivo, i dati potrebbero essere compromessi su tutti. Per i segreti isolati, utilizzare ThisDeviceOnly.

Domande frequenti

In cosa Keychain si differenzia da UserDefaults?

UserDefaults memorizza i dati in chiaro in un file .plist, accessibile durante l'analisi dell'IPA. Keychain crittografa ogni record separatamente, utilizza la crittografia hardware e supporta livelli di accesso, biometria e sincronizzazione tramite iCloud.

Come cancellare Keychain durante il test?

Ad ogni avvio del simulatore iOS, Keychain viene cancellato. Su un dispositivo reale, eliminare l'app — iOS rimuoverà tutti i record Keychain di quel sviluppatore. Per una cancellatura selettiva, chiamare SecItemDelete con gli attributi appropriati.

Due applicazioni possono condividere lo stesso Keychain?

Sì, tramite keychain access groups. Le applicazioni devono avere lo stesso team ID nel profilo di provisioning e entitlements con gli stessi keychain-access-groups. Lo sviluppatore configura l'accesso condiviso in Xcode Capabilities.

Qual è la dimensione massima dei dati in Keychain?

Apple non documenta un limite rigido, ma in pratica si raccomanda di non superare 1–4 KB per record. Per volumi maggiori, utilizzare la crittografia dei file e conservare la chiave in Keychain, mentre i dati stessi in Documents.

Keychain è sicuro su un dispositivo jailbroken?

Su un dispositivo jailbroken, la protezione di Keychain è ridotta perché l'attaccante ottiene accesso root e può leggere il database SQLite di Keychain direttamente. Per dati critici, utilizzare crittografia aggiuntiva con una chiave ottenuta dal server.

Riepilogo

  • Keychain — archivio sicuro iOS per password, chiavi e certificati con crittografia hardware AES-256
  • Security framework fornisce API C: SecItemAdd per scrivere, SecItemCopyMatching per leggere, SecItemDelete per eliminare
  • Classi di dati Keychain: GenericPassword, InternetPassword, Certificate, Key, Identity — ciascuna con il proprio insieme di attributi
  • kSecAttrAccessible controlla il livello di accesso: WhenUnlocked, AfterFirstUnlock, Always, con l'opzione ThisDeviceOnly
  • iCloud Keychain sincronizza i record tra i dispositivi tramite crittografia end-to-end con l'attributo kSecAttrSynchronizable
  • Biometria (Face ID / Touch ID) protegge l'accesso a Keychain tramite kSecAccessControlBiometryCurrentSet
  • Utilizzare Keychain per memorizzare token OAuth, password e chiavi crittografiche — non conservare segreti in UserDefaults

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