Keychain iOS-ben: mi ez, felépítés és munka titkokkal

Szerző: IT Sectr Megjelenés: 2026-04-04 Olvasási idő: 9 perc

Keychain (Kulcstartó) — egy védett tároló iOS-ben, amely jelszavak, kriptográfiai kulcsok, tanúsítványok és bizalmas jegyzetek biztonságos tárolására szolgál. A Apple Security Documentation (2025) szerint a Keychain hardveres titkosítást használ a Secure Enclave-en keresztül minden A7-es chipes és újabb eszközön. Az iOS Keychain architektúrájának megértése elengedhetetlen minden fejlesztő számára a tokenek és alkalmazási titkok helyes tárolásához.

Főbb pontok

  • iOS Keychain — titkosított SQLite adatbázis titkok tárolására hardveres védelemmel a Secure Enclave-en keresztül.
  • Protection Class meghatározza, hogy az adatok mikor érhetőek el: feloldott eszköznél, az első feloldás után vagy mindig.
  • Access Control List (ACL) — a Keychain elemekhez való hozzáférés korlátozásának mechanizmusa, beleértve a biometrikus hitelesítést.
  • SecItemAdd és SecItemCopyMatching — a Security framework fő API-jai elemek írásához és olvasásához.
  • kSecAttrSynchronizable — jelzőzászló, amely lehetővé teszi a Keychain iCloud-on keresztüli szinkronizálását a felhasználó összes eszközén való hozzáféréshez.

Mi az a Keychain iOS-ben?

iOS Keychain — egy védett mechanizmus bizalmas adatok tárolására, amely az Apple operációs rendszerébe van építve. A UserDefaults-tól vagy a szokásos fájloktól eltérően a Keychain minden elemet hardveres szinten titkosít és finom hozzáférés-szabályozást biztosít biztonsági irányelvek alapján.

A Keychain-t az iOS 2.0-ban vezették be, és azóta jelentős változásokon esett át: iOS 7-ben hozzáadták a hardveres kulcsok támogatását a Secure Enclave-en keresztül, iOS 9-ben — a Keychain alkalmazások közötti megosztását Access Groups-on keresztül, iOS 13-ban — a biometrikus kötés támogatását LAContext-en keresztül. Az Apple WWDC Session (2024) szerint az App Store top 100-as listáján szereplő iOS alkalmazások több mint 90%-a használja a Keychain-t hitelesítési tokenek tárolására.

Architektúrálisan a Keychain egy titkosított SQLite adatbázis, amely az alkalmazás homokozóján kívül helyezkedik el. Minden elemet (SecItem) egy külön kulccsal titkosítanak, amelyet a Secure Enclave hardveres kulcsa véd. A Securityd rendszerszolgáltatás kezeli a Keychain-hez való hozzáférést az alkalmazás jogosultságai (entitlements) és a kért védelmi osztály alapján.

A Keychain fontos előnye a többi tárolási móddal szemben: az adatok automatikusan titkosításra és visszafejtésre kerülnek az operációs rendszer által. A fejlesztőnek nem kell manuálisan implementálnia a kriptográfiát — elég a SecItemAdd meghívása a megfelelő paraméterekkel. Az iOS garantálja, hogy a Keychain adatait más alkalmazások nem olvashatják (az Access Groups helyes konfigurációja esetén).

A Keychain architektúrája

A Keychain architektúrája több szintet foglal magában: fizikai (Secure Enclave), rendszer (Security.framework), alkalmazási (API SecItem*) és logikai (Access Groups, Protection Classes). Minden szint megértése segít a titkok tárolásának helyes tervezésében.

SecItemAdd és SecItemCopyMatching

A Keychain-nel való munkavégzés fő API-ja a Security framework függvényei: SecItemAdd hozzáadáshoz, SecItemCopyMatching olvasáshoz, SecItemUpdate frissítéshez és SecItemDelete törléshez. Minden függvény egy query szótárat fogad, amely leírja a keresett vagy mentett elem attribútumait.

A query fő attribútumai: kSecClass — elem típusa (kSecClassGenericPassword, kSecClassKey, kSecClassCertificate), kSecAttrAccount — egyedi azonosító az osztályon belül, kSecValueData — tárolt adatok (Data), kSecAttrAccessible — védelmi osztály. SecItemCopyMatching a kSecReturnData jelzőzászlóval visszaadja az elem adatait, a kSecMatchLimit-tel — az eredmények számát.

Fontos: minden függvény OSStatus-t ad vissza. Sikeres művelet esetén errSecSuccess (0). Hibák: errSecItemNotFound (-25300) — elem nem található, errSecDuplicateItem (-25299) — elem már létezik, errSecAuthFailed (-25293) — biometrikus hitelesítés sikertelen. A fejlesztőnek minden állapotot helyesen kell kezelnie.

Védelmi osztályok (Protection Class)

Protection Class — a kSecAttrAccessible attribútum, amely meghatározza, hogy a Keychain-ben lévő adatok mikor érhetőek el olvasásra. Az iOS hat védelmi osztályt támogat különböző rendelkezésre állási és biztonsági szintekkel.

A legtöbb forgatókönyv esetében ajánlott osztály a kSecAttrAccessibleWhenUnlockedThisDeviceOnly: az adatok csak feloldott eszköz esetén érhetőek el, és nem másolódnak az iCloud Backup-ba. Azon adatokhoz, amelyeknek újraindítás után elérhetőnek kell lenniük (de csak az első feloldás után), használja a kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly-t. A kritikus adatokhoz, amelyek minden hozzáféréskor biometrikus hitelesítést igényelnek, kombinálja a kSecAttrAccessibleWhenUnlockedThisDeviceOnly-t egy biometriát igénylő ACL-lel.

A ThisDeviceOnly utótag nélküli osztályok (kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAfterFirstUnlock) engedélyezik a másolást az iCloud Backup-ba. Ez kényelmes a felhasználó számára, de csökkenti a biztonságot — az adatok visszaállíthatóak a biztonsági másolatból. Hitelesítési tokenekhez mindig használja a ThisDeviceOnly-t.

Access Control Lists (ACL)

Access Control List (ACL) — mechanizmus, amely korlátozza a Keychain elemmel végzett műveleteket a felhasználó hitelesítése alapján. Az ACL-t a SecAccessControlCreateWithFlags segítségével állítják be és a kSecAttrAccessControl attribútumba adják át az elem mentésekor.

Támogatott jelzőzászlók: kSecAccessControlUserPresence — bármilyen hitelesítés (Face ID, Touch ID vagy jelszókód), kSecAccessControlBiometryCurrentSet — csak biometria (jelenleg regisztrált ujjlenyomatok vagy arc), kSecAccessControlDevicePasscode — csak jelszókód. Az ACL minden műveletre vonatkozik: az elem olvasása, frissítése és törlése is hitelesítést igényel.

Az iOS 15+-ban megjelent a kSecAccessControlWatch jelzőzászló — az Apple Watch számára, amely lehetővé teszi a hitelesítést a párosított órán keresztül. Az ACL kombinálható: például kSecAccessControlUserPresence vagy kSecAccessControlBiometryAny opcionális jelszókóddal (.or orientáció).

Adattípusok a Keychain-ben

iOS Keychain négy fő elemosztályt (kSecClass) támogat, mindegyik a saját adattípusának megfelelően. Az osztály helyes megválasztása leegyszerűsíti az elemek szervezését és keresését.

kSecClassGenericPassword — általános jelszó: a leggyakrabban használt osztály. Tetszőleges bináris adatokat (Data) tárol egyedi kulccsal (kSecAttrAccount). Alkalmas tokenekhez, API kulcsokhoz, PIN-kódokhoz. Nem igényel további jogosultságokat (entitlements) a használathoz.

kSecClassInternetPassword — internetes jelszó: hálózati erőforráshoz kapcsolódó adatokat tárol. További attribútumok: kSecAttrServer (szerver domain), kSecAttrProtocol (https, ftp), kSecAttrPort, kSecAttrAuthenticationType. Az iOS automatikusan kitöltheti az ilyen jelszavakat az AutoFill segítségével.

kSecClassKey — kriptográfiai kulcs: titkosítási kulcsok (AES, RSA, EC) tárolására. A kulcs SecKeyRef-ként tárolódik, nem Data-ként. kSecClassCertificate — X.509 tanúsítvány digitális tanúsítványok tárolására és ellenőrzésére. Mindkét osztály megköveteli a kriptográfiai műveletek értését és az attribútumok helyes konfigurálását.

A gyakorlatban a Keychain mobilos alkalmazásokban való használatának 95%-át a kSecClassGenericPassword fedezi a hitelesítési tokenek tárolására és a kSecClassKey a privát titkosítási kulcsok tárolására. A kSecClassCertificate ritkán használt — általában saját PKI-val rendelkező vállalati alkalmazásokban.

Kódpéldák: munka a Keychain-nel Swift-ben

Nézzünk gyakorlati példákat a Keychain-nel való munkára Swift-ben a Security framework használatával. Minden példa tartalmazza a hibakezelést és a Protection Class helyes konfigurációját.

Token mentése és olvasása

Az alappélda elment egy hitelesítési tokent a Keychain-be WhenUnlockedThisDeviceOnly védelemmel. A kulcs (kSecAttrAccount) a szolgáltatás azonosítója, az adatok (kSecValueData) a token Data formátumban.

swift
import Security

enum KeychainError: Error {
    case unexpectedStatus(OSStatus)
}

func saveToken(token: String, service: String) throws {
    let data = Data(token.utf8)
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: "auth_token",
        kSecValueData as String: data,
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemDelete(query as CFDictionary)
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else {
        throw KeychainError.unexpectedStatus(status)
    }
}

func readToken(service: String) throws -> String {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrService as String: service,
        kSecAttrAccount as String: "auth_token",
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    var result: AnyObject?
    let status = SecItemCopyMatching(
        query as CFDictionary, &result
    )
    guard status == errSecSuccess,
        let data = result as? Data else {
        throw KeychainError.unexpectedStatus(status)
    }
    return String(decoding: data, as: UTF8.self)
}

Mentés biometrikus kötéssel

A példa bemutatja a SecAccessControlCreateWithFlags használatát a kulcs biometriához kötéséhez. Minden hozzáférés az elemhez Face ID-t vagy Touch ID-t igényel.

swift
import LocalAuthentication

func saveWithBiometry(data: Data, key: String) throws {
    let accessControl = SecAccessControlCreateWithFlags(
        nil,
        kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
        .biometryCurrentSet,
        nil
    )

    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: key,
        kSecValueData as String: data,
        kSecAttrAccessControl as String: accessControl as Any
    ]

    SecItemDelete(query as CFDictionary)
    let status = SecItemAdd(query as CFDictionary, nil)
    guard status == errSecSuccess else {
        throw KeychainError.unexpectedStatus(status)
    }
}

Keychain Sharing alkalmazások között

A példa bemutatja az Access Group konfigurálását a Keychain megosztott hozzáféréséhez ugyanazon fejlesztő alkalmazásai között. keychain-access-groups entitlement szükséges.

swift
// Capabilities: Keychain Sharing engedélyezve
// App IDs: group.com.example.shared

func saveSharedToken(token: Data) {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "shared_token",
        kSecValueData as String: token,
        kSecAttrAccessGroup as String:
            "group.com.example.shared",
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemAdd(query as CFDictionary, nil)
}

Legjobb gyakorlatok a Keychain használatához

A iOS Keychain helyes használata számos kulcsfontosságú szabály betartását igényli, amelyek megakadályozzák a tipikus sebezhetőségeket és az adatvesztést.

Használja a ThisDeviceOnly-t minden hitelesítési titokhoz: a kSecAttrAccessibleWhenUnlockedThisDeviceOnly garantálja, hogy a tokenek nem kerülnek az iCloud Backup-ba. Ha egy támadó hozzáfér a biztonsági másolathoz, a Keychain adatok ezzel a jelzőzászlóval nem lesznek elérhetőek. Kivételt képeznek azok az adatok, amelyeknek a felhasználó összes eszközén elérhetőnek kell lenniük (például titkosítási kulcsok saját szolgáltatásokhoz), amelyekhez használja a kSecAttrAccessibleWhenUnlocked-t kSecAttrSynchronizable-val.

Ne tároljon nyers jelszavakat — tároljon hasheket vagy munkamenet tokeneket. Az Apple Security Guide (2025) azt ajánlja, hogy soha ne mentse a felhasználó jelszavát a Keychain-be egyszerű szövegként. Ehelyett mentse a sikeres OAuth 2.0 hitelesítés után a szervertől kapott refresh tokent. A jelszó csak a token megszerzéséhez használható, és azonnal törlődik a memóriából.

Kezelje helyesen a Keychain hibákat: minden Keychain művelet OSStatus-t ad vissza, amelyet ellenőrizni kell. Különös figyelmet fordítson az errSecItemNotFound (token lejárt vagy törölve) és az errSecAuthFailed (biometria sikertelen) esetekre. Az első esetben az alkalmazásnak új hitelesítést kell kérnie, a másodikban — alternatív módszert kell mutatnia a felhasználónak (jelszókód). Soha ne hagyja figyelmen kívül az errSecItemNotFound állapotot — ez az alkalmazás összeomlásához vezet, amikor nil-t próbál olvasni.

Tesztelje a Keychain-t valós eszközön: a szimulátor nem rendelkezik Secure Enclave-val és nem támogatja a biometrikus ACL-eket. Mindig ellenőrizze a forgatókönyveket: első indítás, visszaállítás biztonsági másolatból, eszköz jelszó módosítása, alkalmazás eltávolítása és újratelepítése. Valós eszközön a Keychain megmarad az alkalmazás eltávolítása után, de csak ha nem használta a kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly jelzőzászlót — ez a jelzőzászló törlődik a jelszókód eltávolításakor.

Minimalizálja a Keychain műveletek számát: minden olvasási vagy írási művelet a Securityd rendszerszolgáltatás meghívása, amely blokkolhatja a szálat. Gyorsítótárolja a beolvasott tokeneket a memóriában a munkamenet idejére, és csak az alkalmazás újraindításakor vagy hitelesítési hiba (401 a szervertől) esetén férjen hozzá újra a Keychain-hez. Az iOS automatikusan blokkolja a Keychain-t az eszköz zárolásakor, ezért tervezze az olvasást LAContext-en keresztül biometria kéréssel.

Gyakran Ismételt Kérdések

Menthetek adatokat a Keychain-be és olvashatom őket újraindítás után?

Igen, használja a kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly vagy a kSecAttrAccessibleAfterFirstUnlock védelmi osztályt. Az adatok az újraindítás utáni első eszközfeloldástól kezdve érhetőek el. Az alkalmazás indításakor történő automatikus hozzáféréshez (feloldásra várakozás nélkül) használja a kSecAttrAccessibleAlways-t, de ez csökkenti a biztonságot.

Hogyan töröljem a Keychain-t a felhasználó kijelentkezésekor?

Hívja meg a SecItemDelete-t egy kSecClass-t tartalmazó query-vel minden adattípushoz. Az alkalmazás összes elemenek teljes törléséhez: SecItemDelete([kSecClass as String: kSecClassGenericPassword] as CFDictionary). Ismételje meg a kSecClassKey, kSecClassCertificate és kSecClassInternetPassword esetében.

Mi a különbség a kSecAttrAccessible és a kSecAttrAccessControl között?

kSecAttrAccessible meghatározza, hogy az adatok mikor érhetőek el (feloldáskor, első feloldás után stb.). A kSecAttrAccessControl meghatározza, ki férhet hozzá (biometria, jelszókód, bármilyen hitelesítés). Ezek kombinálódnak: először Protection Class, majd ACL. Például az adatok csak feloldáskor ÉS csak Face ID után érhetőek el.

Miért ad vissza a SecItemCopyMatching errSecItemNotFound-t?

Okok: az elem soha nem lett mentve, az elem törlödött a jelszókód eltávolításakor (ha kSecAttrAccessibleWhenPasscodeSet volt használva), az alkalmazás újra lett telepítve (a Keychain megmarad, de nem állítódik vissza a biztonsági másolatból új eszközön), az Access Group vagy a fejlesztői csapat azonosítója megváltozott. Ellenőrizze a kSecAttrService és kSecAttrAccount értékeket.

Hogyan ellenőrizzem, hogy az eszköz támogatja-e a biometriát a Keychain-ben?

Használja a LAContext-et a LocalAuthentication-ból: hívja meg a context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) függvényt. Ha true-t ad vissza — az eszköz támogatja a Touch ID-t vagy a Face ID-t. Keychain ACL-hez használja a biometryCurrentSet (csak aktuális biometrikus adatok) vagy a biometryAny (bármely korábban regisztrált) jelzőzászlót.

Összefoglaló

  • iOS Keychain — hardveresen védett titkok tárolója Secure Enclave-en keresztüli titkosítással és ACL-en keresztüli hozzáférés-szabályozással.
  • Security framework biztosítja a SecItemAdd, SecItemCopyMatching, SecItemUpdate és SecItemDelete függvényeket az elemekkel való munkához.
  • Protection Class (kSecAttrAccessible) a forgatókönyv alapján választandó: WhenUnlockedThisDeviceOnly — standard tokenekhez.
  • ACL biometriával (kSecAttrAccessControl) Face ID vagy Touch ID követelményt ad hozzá minden olvasási művelethez.
  • kSecClassGenericPassword az esetek 95%-át lefedi — tokenek, API kulcsok, PIN-kódok és jegyzetek tárolása.
  • ThisDeviceOnly megakadályozza a titkok iCloud Backup-ba másolását — kötelező hitelesítési tokenekhez.
  • Az OSStatus helyes kezelése és tesztelés valós eszközön — kötelező gyakorlatok a megbízható Keychain használathoz.

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.

Projekt megbeszélése

Olvassa el is