Keychain — egy biztonságos hitelesítőadat-tároló iOS, watchOS, macOS és tvOS rendszerekben, amely jelszavakat, kulcsokat és tanúsítványokat kezel hardverszinten. A UserDefaults-szal ellentétben a Keychainben lévő adatok titkosítva vannak és az alkalmazás homokozója elkülöníti őket. A Apple Developer Documentation szerint a Keychain a Secure Enclave mechanizmusokat és az AES-256 hardveres titkosítást használja a bizalmas információk védelmére.
Főbb pontok
Keychain — az Apple operációs rendszerének biztonságos adatbázisa, amely jelszavak, kriptográfiai kulcsok, tanúsítványok és más bizalmas adatok biztonságos tárolására szolgál. A Keychain először 1999-ben jelent meg a Mac OS 8.6-ban, iOS-en pedig az első SDK-verziótól kezdve.
A Keychain megoldja a mobilfejlesztés alapvető problémáját: a titkok (tokenek, jelszavak, titkosítási kulcsok) tárolását a védtelen fájlrendszerben. A UserDefaults-szal vagy SQLite-tal ellentétben a Keychainben lévő adatok titkosított formában vannak tárolva és automatikusan titkosítódnak a lemezre íráskor.
Minden iOS-alkalmazás egy elkülönített homokozóban működik, és csak a saját keychain-jéhez fér hozzá. A fejlesztő azonban konfigurálhat megosztott hozzáférést a Keychainhez azonos fejlesztő alkalmazásai között keychain access groups segítségével. Az iCloud Keychain felhasználó emellett szinkronizálja az adatokat az eszközök között end-to-end titkosítással.
A Apple Security White Paper (2025) szerint a Keychain AES-256 hardveres titkosítást használ az eszköz egyedi azonosítójához (UID) kötött kulccsal, ami az adatokat az eszközből való kinyeréskor hozzáférhetetlenné teszi.
A Keychain rétegezett szolgáltatásként működik: az alkalmazás a Security framework-öt hívja meg, amely a securityd démonnal kommunikál, ami a titkosított SQLite Keychain adatbázist kezeli. Minden bejegyzés külön kulccsal van titkosítva, és maguk a kulcsok a Secure Enclave hardvermodul által védettek az A7 chipes és újabb eszközökön.
A Security framework C interfészt biztosít a Keychain Services-szel való munkához. Fő függvények: SecItemAdd (hozzáadás), SecItemCopyMatching (keresés), SecItemUpdate (frissítés) és SecItemDelete (törlés). Minden művelet egy CFDictionaryRef attribútumszótárt fogad, amely leírja a kérés típusát.
Az adatok osztályok szerint vannak osztályozva: kSecClassGenericPassword (tetszőleges jelszó), kSecClassInternetPassword (jelszó internetszolgáltatáshoz), kSecClassCertificate (tanúsítvány), kSecClassKey (kriptográfiai kulcs) és kSecClassIdentity (kulcs és tanúsítvány kombinációja).
Jelszó mentésekor az alkalmazás egy szótárt hoz létre attribútumokkal: szolgáltatás, fiók, hozzáférési szint, címke. Security framework továbbítja az adatokat a securityd démonnak, amely az eszközhöz kötött kulccsal titkosítja a bejegyzést és elmenti a Keychain SQLite-ba. A kinyerés hasonlóan történik: kérés attribútumok alapján, keresés, visszafejtés és adatok visszaadása.
Fontos jellemző: az alkalmazás törlésekor az iOS automatikusan kitörli a Keychain-ből az alkalmazás által létrehozott bejegyzéseket (iOS 10.3+ óta). Az alkalmazás újratelepítésekor az előző telepítés Keychain-adatai hozzáférhetetlenek, kivéve ha iCloud Keychain-t használtak.
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)
}
A Keychain öt fő adatosztályt támogat, mindegyiknek saját attribútumkészlete és alkalmazási területe van. Az osztályválasztástól függ, hogy mely keresőkulcsok érhetők el és hogyan titkosítódnak az adatok.
A kSecClassGenericPassword és kSecClassInternetPassword osztályok szöveges jelszavak tárolására szolgálnak. Az internetes verzió emellett tárolja a szerver adatait: domain, protokoll, port és hitelesítési útvonal. A GenericPassword bármilyen jelszó tárolására használható szerverhez kötés nélkül.
Internetes jelszó mentésekor megadható kSecAttrServer (domain), kSecAttrProtocol (HTTPS, FTP stb.), kSecAttrPort és kSecAttrPath. Ez lehetővé teszi a bejegyzés pontos azonosítását az AutoFill segítségével történő automatikus kitöltéskor.
A kSecClassKey osztály szimmetrikus (AES) és aszimmetrikus (RSA, EC) kulcsokat tárol. A kSecClassCertificate osztály — X.509 tanúsítványokat. A kSecClassIdentity osztály egyesíti a privát kulcsot és a megfelelő tanúsítványt egy bejegyzésben.
Aszimmetrikus kulcsokhoz a Keychain támogatja az attribútumokat: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (mentés a Keychainbe). Tanúsítványokhoz: kSecAttrLabel (ember által olvasható név), kSecAttrSubject (tulajdonos DN), kSecAttrIssuer (kibocsátó DN).
| Keychain osztály | Cél | Adattípus |
|---|---|---|
| kSecClassGenericPassword | Alkalmazás jelszava | Data (NSString) |
| kSecClassInternetPassword | Szerver jelszava | Data + szerver attribútumok |
| kSecClassCertificate | X.509 tanúsítvány | SecCertificate |
| kSecClassKey | Kriptográfiai kulcs | SecKey |
| kSecClassIdentity | Kulcs + tanúsítvány | SecIdentity |
A natív iOS kódban a Keychain-nel való interakció fő interfésze — a Security framework függvényei. Swift és Objective-C számára egy C interfész érhető el, kényelmes függvényekbe csomagolva.
A SecItemAdd függvény új elemet ad hozzá a Keychainhez. Bemenetként egy szótárt fogad osztállyal, adatokkal és attribútumokkal. Visszaadja az errSecSuccess (0) státuszt vagy hibakódot. A SecItemCopyMatching függvény attribútumok alapján keres és visszaadja a talált adatokat.
A kereséshez a kSecReturnData flag használatos — ha true, a függvény visszaadja a bejegyzés tartalmát. A kSecMatchLimit flag határozza meg az eredmények számát: kSecMatchLimitOne (egy) vagy kSecMatchLimitAll (összes).
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
}
A SecItemUpdate lehetővé teszi egy meglévő bejegyzés attribútumainak vagy adatainak módosítását. A SecItemDelete törli az átadott szótárnak megfelelő összes bejegyzést. Törléskor fontos elegendő attribútumot megadni, hogy ne töröljük véletlenül mások bejegyzéseit a megosztott keychainben.
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)
}
Minden Keychain-bejegyzés rendelkezik a kSecAttrAccessible attribútummal, amely meghatározza, hogy az adatok mikor érhetők el olvasásra. Ez kritikus a biztonság szempontjából: a rossz hozzáférési szint sebezhetővé teheti az adatokat, vagy éppen ellenkezőleg, hozzáférhetetlenné a szükséges pillanatban.
kSecAttrAccessibleWhenUnlocked — az adatok csak akkor érhetők el, ha az eszköz fel van oldva. kSecAttrAccessibleAfterFirstUnlock — az első feloldás után érhetők el újraindítást követően. kSecAttrAccessibleAlways — mindig elérhető (nem ajánlott). A ThisDeviceOnly utótag megtiltja az adatok biztonsági mentésen keresztüli átvitelét.
Secure Enclave rendszerű eszközökön a Keychain titkosítási kulcs tovább védhető biometriával: kSecAccessControlBiometryCurrentSet vagy kSecAccessControlUserPresence. Ez Face ID vagy Touch ID követelményt ad hozzá minden olvasási művelethez.
iCloud Keychain szinkronizálja a bejegyzéseket Apple-eszközök között end-to-end titkosítással. Az Apple nem fér hozzá a visszafejtett adatokhoz. A szinkronizáció engedélyezéséhez adja hozzá a kSecAttrSynchronizable attribútumot kCFBooleanTrue értékkel.
Fontos: a szinkronizált bejegyzések nem tartalmazhatják a ThisDeviceOnly attribútumot, mert más eszközökön is elérhetőnek kell lenniük. Az összes eszköz elvesztésekor az iCloud Keychain helyreállítási kóddal vagy iCloud biztonsági kulccsal állítható helyre.
Hitelesítési tokenekhez használja a kSecAttrAccessibleWhenUnlockedThisDeviceOnly-t — az adatok csak feloldott eszközön érhetők el és nem másolódnak biztonsági mentésbe. Háttérfeladatok számára elérhető tanúsítványokhoz használja a kSecAttrAccessibleAfterFirstUnlock-ot. Soha ne használja a kSecAttrAccessibleAlways-t bizalmas adatokhoz.
Ajánlott mindig hozzáadni a ThisDeviceOnly utótagot a szinkronizációt nem igénylő adatokhoz. Ez megakadályozza a titkok véletlen másolását iCloud vagy iTunes biztonsági mentésbe, ahonnan elemzőeszközökkel kinyerhetők. Kritikus adatokhoz kombinálja az elérhetőséget a kSecAccessControlUserPresence-szel — ez biometria- vagy kódkövetelményt ad hozzá a bejegyzés visszafejtéséhez.
Az iCloud Keychain használatakor vegye figyelembe, hogy a szinkronizált bejegyzések a felhasználó összes eszközén elérhetők: ha egy támadó hozzáfér egy eszközhöz, az adatok az összes eszközön veszélybe kerülhetnek. Elkülönített titkokhoz használja a ThisDeviceOnly-t.
Gyakran ismételt kérdések
UserDefaults nyílt formában tárolja az adatokat egy .plist fájlban, amely IPA-elemzéskor elérhető. A Keychain minden bejegyzést külön titkosít, hardveres titkosítást használ és támogatja a hozzáférési szinteket, biometriát és iCloudon keresztüli szinkronizációt.
Minden indításkor az iOS-szimulátoron a Keychain kiürül. Valós eszközön törölje az alkalmazást — az iOS törli a fejlesztő összes Keychain-bejegyzését. Szelektív törléshez hívja meg a SecItemDelete-et a megfelelő attribútumokkal.
Igen, keychain access groups segítségével. Az alkalmazásoknak azonos team ID-val kell rendelkezniük az aláírásban és entitlements-ben azonos keychain-access-groups-szel. A fejlesztő az Xcode Capabilities-ben konfigurálja a megosztott hozzáférést.
Az Apple nem dokumentál szigorú korlátot, de a gyakorlatban ajánlott nem túllépni az 1–4 KB-ot bejegyzésenként. Nagy mennyiségekhez használjon fájltitkosítást és a kulcs Keychainben tárolását, az adatokat pedig a Documents mappában.
Jailbreak után a Keychain védelme csökken, mert a támadó root hozzáférést szerez és közvetlenül olvashatja a Keychain SQLite-ot. Kritikus adatokhoz használjon további titkosítást a szerverről kapott kulccsal.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is