Keychain — concepte cheie, arhitectură și cum funcționează

Autor: IT Sectr Publicat: 2026-03-14 Timp de citire: 10 min

Keychain — este un depozit securizat de date de autentificare în iOS, watchOS, macOS și tvOS, care gestionează parole, chei și certificate la nivel hardware. Spre deosebire de UserDefaults, datele din Keychain sunt criptate și izolate prin sandbox-ul aplicației. Conform Apple Developer Documentation, Keychain utilizează mecanismele Secure Enclave și criptarea hardware AES-256 pentru protejarea informațiilor confidențiale.

Principalele puncte

  • Keychain — depozitul sistemic iOS pentru parole, chei și certificate cu criptare hardware
  • Security framework oferă funcțiile C SecItemAdd, SecItemCopyMatching și SecItemDelete pentru lucrul cu Keychain
  • Accesul la Keychain este limitat de sandbox-ul aplicației, dar este posibil accesul partajat prin keychain access groups
  • Atributul kSecAttrAccessible determină nivelul de protecție: de la Always la WhenUnlockedThisDeviceOnly
  • Keychain suportă stocarea parolelor, cheilor simetrice și asimetrice, certificatelor X.509

Ce este Keychain?

Keychain — este o bază de date securizată a sistemului de operare Apple, destinată stocării sigure a parolelor, cheilor criptografice, certificatelor și altor date confidențiale. Keychain a apărut pentru prima dată în Mac OS 8.6 în 1999, iar pe iOS — din prima versiune a SDK-ului.

Definiție și scop

Keychain rezolvă o problemă fundamentală a dezvoltării mobile: stocarea secretelor (token-uri, parole, chei de criptare) în sistemul de fișiere neprotejat. Spre deosebire de UserDefaults sau SQLite, datele din Keychain sunt stocate în formă criptată și se criptează automat la scrierea pe disc.

Fiecare aplicație iOS funcționează într-un sandbox izolat și are acces doar la propriul keychain. Cu toate acestea, dezvoltatorul poate configura accesul partajat la Keychain între aplicațiile aceluiași dezvoltator prin keychain access groups. Utilizatorul iCloud Keychain sincronizează suplimentar datele între dispozitive prin criptare end-to-end.

Conform Apple Security White Paper (2025), Keychain utilizează criptarea hardware AES-256 cu o cheie legată de identificatorul unic al dispozitivului (UID), ceea ce face datele inaccesibile la extragerea din dispozitiv.

Cum funcționează Keychain pe iOS?

Keychain funcționează ca un serviciu pe niveluri: aplicația apelează Security framework, care interacționează cu demonul securityd, ce gestionează baza de date criptată SQLite a Keychain. Fiecare înregistrare este criptată cu o cheie separată, iar cheile în sine sunt protejate de modulul hardware Secure Enclave pe dispozitivele cu cip A7 și mai noi.

Arhitectura Security framework

Security framework oferă o interfață C pentru lucrul cu Keychain Services. Funcțiile principale: SecItemAdd (adăugare), SecItemCopyMatching (căutare), SecItemUpdate (actualizare) și SecItemDelete (ștergere). Fiecare operație primește un dicționar de atribute CFDictionaryRef care descrie tipul cererii.

Datele sunt clasificate după clase: kSecClassGenericPassword (parolă arbitrară), kSecClassInternetPassword (parolă pentru serviciu internet), kSecClassCertificate (certificat), kSecClassKey (cheie criptografică) și kSecClassIdentity (combinație cheie și certificat).

Procesul de salvare a datelor

La salvarea parolei, aplicația formează un dicționar cu atribute: serviciu, cont, nivel de acces, etichetă. Security framework transmite datele demonului securityd, care criptează înregistrarea cu o cheie legată de dispozitiv și o salvează în Keychain SQLite. Extragerea are loc similar: cerere după atribute, căutare, decriptare și returnare a datelor.

O caracteristică importantă: la ștergerea aplicației, iOS curăță automat Keychain de înregistrările create de această aplicație (din iOS 10.3+). La reinstalarea aplicației, datele Keychain din instalarea anterioară sunt inaccesibile, dacă nu s-a folosit 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)
}

Tipuri de date în Keychain

Keychain suportă cinci clase principale de date, fiecare având propriul set de atribute și domeniu de aplicare. De alegerea clasei depinde ce chei de căutare sunt disponibile și cum sunt criptate datele.

Parole și conturi

Clasele kSecClassGenericPassword și kSecClassInternetPassword sunt destinate stocării parolelor text. Versiunea internet stochează suplimentar datele serverului: domeniu, protocol, port și cale de autentificare. GenericPassword este folosit pentru stocarea oricăror parole fără legătură cu un server.

La salvarea parolei de internet se pot specifica kSecAttrServer (domeniu), kSecAttrProtocol (HTTPS, FTP etc.), kSecAttrPort și kSecAttrPath. Acest lucru permite identificarea precisă a înregistrării la completarea automată prin AutoFill.

Chei criptografice și certificate

Clasa kSecClassKey stochează chei simetrice (AES) și asimetrice (RSA, EC). Clasa kSecClassCertificate — certificate X.509. Clasa kSecClassIdentity combină cheia privată și certificatul corespunzător într-o singură înregistrare.

Pentru cheile asimetrice, Keychain suportă atributele: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (dacă se salvează în Keychain). Pentru certificate: kSecAttrLabel (nume lizibil pentru om), kSecAttrSubject (DN al proprietarului), kSecAttrIssuer (DN al emitentului).

Clasa KeychainDestinațieTip de date
kSecClassGenericPasswordParolă aplicațieData (NSString)
kSecClassInternetPasswordParolă serverData + atribute server
kSecClassCertificateCertificat X.509SecCertificate
kSecClassKeyCheie criptograficăSecKey
kSecClassIdentityCheie + certificatSecIdentity

Lucrul cu Keychain prin API

Interfața principală de interacțiune cu Keychain în codul nativ iOS — funcțiile Security framework. Pentru Swift și Objective-C este disponibilă o interfață C, împachetată în funcții convenabile.

Operațiile de bază SecItemAdd și SecItemCopyMatching

Funcția SecItemAdd adaugă un element nou în Keychain. La intrare primește un dicționar cu clasa, datele și atributele. Returnează statusul errSecSuccess (0) sau un cod de eroare. Funcția SecItemCopyMatching execută căutarea după atribute și returnează datele găsite.

Pentru căutare se folosește flagul kSecReturnData — dacă este true, funcția returnează conținutul înregistrării. Flagul kSecMatchLimit determină numărul de rezultate: kSecMatchLimitOne (unul) sau kSecMatchLimitAll (toate).

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
}

Ștergerea și actualizarea înregistrărilor

SecItemUpdate permite modificarea atributelor sau datelor unei înregistrări existente. SecItemDelete șterge toate înregistrările corespunzătoare dicționarului transmis. La ștergere este important să se specifice suficiente atribute pentru a nu șterge accidental înregistrări ale altora în shared keychain.

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

Niveluri de acces și protecția datelor

Fiecare înregistrare Keychain are atributul kSecAttrAccessible, care determină când datele sunt disponibile pentru citire. Acest lucru este critic pentru securitate: un nivel de acces greșit poate face datele vulnerabile sau, dimpotrivă, inaccesibile în momentul necesar.

Constante de disponibilitate

kSecAttrAccessibleWhenUnlocked — datele sunt disponibile doar când dispozitivul este deblocat. kSecAttrAccessibleAfterFirstUnlock — disponibile după prima deblocare după repornire. kSecAttrAccessibleAlways — disponibile întotdeauna (nerecomandat). Postfixul ThisDeviceOnly interzice transferul datelor prin backup.

Pe dispozitivele cu Secure Enclave, cheia de criptare Keychain poate fi suplimentar protejată prin biometrie: kSecAccessControlBiometryCurrentSet sau kSecAccessControlUserPresence. Acest lucru adaugă cerința Face ID sau Touch ID pentru fiecare operație de citire.

iCloud Keychain și sincronizarea

iCloud Keychain sincronizează înregistrările între dispozitivele Apple prin criptare end-to-end. Apple nu are acces la datele decriptate. Pentru activarea sincronizării, adăugați atributul kSecAttrSynchronizable cu valoarea kCFBooleanTrue.

Important: înregistrările sincronizate nu pot conține atributul ThisDeviceOnly, deoarece trebuie să fie disponibile pe alte dispozitive. La pierderea tuturor dispozitivelor, iCloud Keychain se restabilește printr-un cod de recuperare sau o cheie de rezervă iCloud.

Best Practices pentru alegerea nivelului de acces

Pentru token-urile de autentificare folosiți kSecAttrAccessibleWhenUnlockedThisDeviceOnly — datele sunt disponibile doar la dispozitivul deblocat și nu se copiază în backup. Pentru certificatele care trebuie să fie disponibile sarcinilor de fundal, folosiți kSecAttrAccessibleAfterFirstUnlock. Nu folosiți niciodată kSecAttrAccessibleAlways pentru date confidențiale.

Se recomandă să adăugați întotdeauna postfixul ThisDeviceOnly pentru datele care nu necesită sincronizare. Acest lucru previne copierea accidentală a secretelor în iCloud sau iTunes backup, de unde pot fi extrase cu instrumente de analiză. Pentru datele critice, combinați disponibilitatea cu kSecAccessControlUserPresence — acest lucru adaugă cerința de biometrie sau cod pentru decriptarea înregistrării.

La utilizarea iCloud Keychain rețineți că înregistrările sincronizate sunt disponibile pe toate dispozitivele utilizatorului: dacă un atacator obține acces la un dispozitiv, datele pot fi compromise pe toate. Pentru secrete izolate, folosiți ThisDeviceOnly.

Întrebări frecvente

Cu ce se deosebește Keychain de UserDefaults?

UserDefaults stochează datele în formă deschisă în fișierul .plist, accesibil la analiza IPA. Keychain criptează fiecare înregistrare separat, utilizează criptare hardware și suportă niveluri de acces, biometrie și sincronizare prin iCloud.

Cum curăț Keychain la testare?

La fiecare pornire pe simulatorul iOS, Keychain se curăță. Pe dispozitiv real, ștergeți aplicația — iOS va șterge toate înregistrările Keychain ale acestui dezvoltator. Pentru curățarea selectivă, apelați SecItemDelete cu atributele corespunzătoare.

Pot două aplicații să folosească un Keychain partajat?

Da, prin keychain access groups. Aplicațiile trebuie să aibă același team ID în semnătură și entitlements cu același keychain-access-groups. Dezvoltatorul configurează accesul partajat în Xcode Capabilities.

Care este dimensiunea maximă a datelor în Keychain?

Apple nu documentează o limită strictă, dar în practică se recomandă să nu se depășească 1–4 KB per înregistrare. Pentru volume mari, folosiți criptarea fișierelor și stocarea cheii în Keychain, iar datele în sine — în Documents.

Este Keychain sigur după jailbreak?

La jailbreak, protecția Keychain se reduce, deoarece atacatorul obține acces root și poate citi Keychain SQLite direct. Pentru date critice, folosiți criptare suplimentară cu o cheie obținută de pe server.

Rezumat

  • Keychain — depozit securizat iOS pentru parole, chei și certificate cu criptare hardware AES-256
  • Security framework oferă C-API: SecItemAdd pentru scriere, SecItemCopyMatching pentru citire, SecItemDelete pentru ștergere
  • Clase de date Keychain: GenericPassword, InternetPassword, Certificate, Key, Identity — fiecare cu propriul set de atribute
  • kSecAttrAccessible gestionează nivelul de acces: WhenUnlocked, AfterFirstUnlock, Always, cu opțiunea ThisDeviceOnly
  • iCloud Keychain sincronizează înregistrările între dispozitive prin criptare end-to-end cu atributul kSecAttrSynchronizable
  • Biometria (Face ID / Touch ID) protejează accesul la Keychain prin kSecAccessControlBiometryCurrentSet
  • Folosiți Keychain pentru stocarea token-urilor OAuth, parolelor și cheilor criptografice — nu stocați secrete în UserDefaults

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.

Discutați proiectul

Citiți și