Keychain — je bezpečné úložiště přihlašovacích údajů v iOS, watchOS, macOS a tvOS, které spravuje hesla, klíče a certifikáty na hardwarové úrovni. Na rozdíl od UserDefaults jsou data v Keychain šifrována a izolována v sandboxu aplikace. Podle Apple Developer Documentation používá Keychain mechanismy Secure Enclave a hardwarové šifrování AES-256 k ochraně důvěrných informací.
Hlavní body
Keychain — je bezpečná databáze operačního systému Apple, určená pro bezpečné ukládání hesel, kryptografických klíčů, certifikátů a dalších důvěrných dat. Keychain se poprvé objevil v Mac OS 8.6 v roce 1999 a v iOS — od první verze SDK.
Keychain řeší základní problém mobilního vývoje: ukládání tajemství (tokenů, hesel, šifrovacích klíčů) v nechráněném souborovém systému. Na rozdíl od UserDefaults nebo SQLite jsou data v Keychain uložena v šifrované podobě a automaticky se šifrují při zápisu na disk.
Každá aplikace iOS pracuje v izolovaném sandboxu a má přístup pouze ke svému keychain. Vývojář však může nakonfigurovat sdílený přístup k Keychain mezi aplikacemi stejného vývojáře prostřednictvím keychain access groups. Uživatel iCloud Keychain navíc synchronizuje data mezi zařízeními prostřednictvím end-to-end šifrování.
Podle Apple Security White Paper (2025) používá Keychain hardwarové šifrování AES-256 s klíčem vázaným na jedinečný identifikátor zařízení (UID), což činí data nepřístupná při extrakci ze zařízení.
Keychain funguje jako vrstvená služba: aplikace volá Security framework, který komunikuje s démonem securityd, jenž spravuje šifrovanou SQLite databázi Keychain. Každý záznam je šifrován samostatným klíčem a samotné klíče jsou chráněny hardwarovým modulem Secure Enclave na zařízeních s čipem A7 a novějším.
Security framework poskytuje C rozhraní pro práci s Keychain Services. Hlavní funkce: SecItemAdd (přidání), SecItemCopyMatching (vyhledávání), SecItemUpdate (aktualizace) a SecItemDelete (smazání). Každá operace přijímá slovník atributů CFDictionaryRef popisující typ požadavku.
Data jsou klasifikována podle tříd: kSecClassGenericPassword (libovolné heslo), kSecClassInternetPassword (heslo k internetové službě), kSecClassCertificate (certifikát), kSecClassKey (kryptografický klíč) a kSecClassIdentity (kombinace klíče a certifikátu).
Při ukládání hesla aplikace vytvoří slovník s atributy: služba, účet, úroveň přístupu, štítek. Security framework předá data démonu securityd, který zašifruje záznam klíčem vázaným na zařízení a uloží do Keychain SQLite. Extrakce probíhá analogicky: dotaz podle atributů, vyhledání, dešifrování a vrácení dat.
Důležitá vlastnost: při smazání aplikace iOS automaticky vyčistí Keychain od záznamů vytvořených touto aplikací (od iOS 10.3+). Při přeinstalaci aplikace jsou Keychain data z předchozí instalace nepřístupná, pokud nebyl použit iCloud Keychain.
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)
}
Keychain podporuje pět hlavních tříd dat, z nichž každá má svou vlastní sadu atributů a oblast použití. Od výběru třídy závisí, které vyhledávací klíče jsou dostupné a jak jsou data šifrována.
Třídy kSecClassGenericPassword a kSecClassInternetPassword jsou určeny pro ukládání textových hesel. Internetová verze navíc ukládá data serveru: doménu, protokol, port a cestu autentizace. GenericPassword se používá pro ukládání libovolných hesel bez vazby na server.
Při ukládání internetového hesla lze zadat kSecAttrServer (doména), kSecAttrProtocol (HTTPS, FTP atd.), kSecAttrPort a kSecAttrPath. To umožňuje přesnou identifikaci záznamu při automatickém vyplňování prostřednictvím AutoFill.
Třída kSecClassKey ukládá symetrické (AES) a asymetrické (RSA, EC) klíče. Třída kSecClassCertificate — certifikáty X.509. Třída kSecClassIdentity spojuje soukromý klíč a odpovídající certifikát do jednoho záznamu.
Pro asymetrické klíče Keychain podporuje atributy: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (zda uložit do Keychain). Pro certifikáty: kSecAttrLabel (člověkem čitelný název), kSecAttrSubject (DN vlastníka), kSecAttrIssuer (DN vydavatele).
| Třída Keychain | Účel | Typ dat |
|---|---|---|
| kSecClassGenericPassword | Heslo aplikace | Data (NSString) |
| kSecClassInternetPassword | Heslo k serveru | Data + atributy serveru |
| kSecClassCertificate | Certifikát X.509 | SecCertificate |
| kSecClassKey | Kryptografický klíč | SecKey |
| kSecClassIdentity | Klíč + certifikát | SecIdentity |
Hlavní rozhraní pro interakci s Keychain v nativním iOS kódu — funkce Security framework. Pro Swift a Objective-C je k dispozici jedno C rozhraní, zabalené do pohodlných funkcí.
Funkce SecItemAdd přidá nový prvek do Keychain. Na vstupu přijímá slovník s třídou, daty a atributy. Vrací status errSecSuccess (0) nebo kód chyby. Funkce SecItemCopyMatching provádí vyhledávání podle atributů a vrací nalezená data.
Pro vyhledávání se používá příznak kSecReturnData — pokud je true, funkce vrací obsah záznamu. Příznak kSecMatchLimit určuje počet výsledků: kSecMatchLimitOne (jeden) nebo kSecMatchLimitAll (všechny).
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
}
SecItemUpdate umožňuje změnit atributy nebo data existujícího záznamu. SecItemDelete maže všechny záznamy odpovídající předanému slovníku. Při mazání je důležité zadat dostatek atributů, aby nedošlo k náhodnému smazání cizích záznamů ve sdíleném keychain.
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)
}
Každý záznam Keychain má atribut kSecAttrAccessible, který určuje, kdy jsou data dostupná pro čtení. To je kritické pro bezpečnost: nesprávná úroveň přístupu může učinit data zranitelnými nebo naopak nedostupnými v pravý okamžik.
kSecAttrAccessibleWhenUnlocked — data jsou dostupná pouze když je zařízení odemčeno. kSecAttrAccessibleAfterFirstUnlock — dostupná po prvním odemčení po restartu. kSecAttrAccessibleAlways — vždy dostupná (nedoporučuje se). Přípona ThisDeviceOnly zakazuje přenos dat prostřednictvím zálohy.
Na zařízeních s Secure Enclave může být šifrovací klíč Keychain dále chráněn biometrií: kSecAccessControlBiometryCurrentSet nebo kSecAccessControlUserPresence. To přidává požadavek na Face ID nebo Touch ID pro každou operaci čtení.
iCloud Keychain synchronizuje záznamy mezi zařízeními Apple prostřednictvím end-to-end šifrování. Apple nemá přístup k dešifrovaným datům. Pro aktivaci synchronizace přidejte atribut kSecAttrSynchronizable s hodnotou kCFBooleanTrue.
Důležité: synchronizované záznamy nemohou obsahovat atribut ThisDeviceOnly, protože musí být dostupné na jiných zařízeních. Při ztrátě všech zařízení se iCloud Keychain obnoví pomocí obnovovacího kódu nebo záložního klíče iCloud.
Pro tokeny autentizace použijte kSecAttrAccessibleWhenUnlockedThisDeviceOnly — data jsou dostupná pouze na odemčeném zařízení a nekopírují se do zálohy. Pro certifikáty, které musí být dostupné pro úlohy na pozadí, použijte kSecAttrAccessibleAfterFirstUnlock. Nikdy nepoužívejte kSecAttrAccessibleAlways pro důvěrná data.
Doporučuje se vždy přidávat příponu ThisDeviceOnly pro data, která nevyžadují synchronizaci. To zabraňuje náhodnému kopírování tajemství do iCloud nebo iTunes zálohy, odkud mohou být extrahována analytickými nástroji. Pro kritická data kombinujte dostupnost s kSecAccessControlUserPresence — to přidává požadavek na biometrii nebo kód pro dešifrování záznamu.
Při použití iCloud Keychain mějte na paměti, že synchronizované záznamy jsou dostupné na všech zařízeních uživatele: pokud útočník získá přístup k jednomu zařízení, data mohou být kompromitována na všech. Pro izolovaná tajemství použijte ThisDeviceOnly.
Často kladené otázky
UserDefaults ukládá data v otevřené podobě v souboru .plist, přístupném při analýze IPA. Keychain šifruje každý záznam samostatně, používá hardwarové šifrování a podporuje úrovně přístupu, biometrii a synchronizaci přes iCloud.
Při každém spuštění na iOS simulátoru se Keychain čistí. Na reálném zařízení odstraňte aplikaci — iOS smaže všechny Keychain záznamy tohoto vývojáře. Pro selektivní čištění zavolejte SecItemDelete s odpovídajícími atributy.
Ano, prostřednictvím keychain access groups. Aplikace musí mít stejné team ID v podpisu a entitlements se stejným keychain-access-groups. Vývojář konfiguruje sdílený přístup v Xcode Capabilities.
Apple nedokumentuje přísný limit, ale v praxi se doporučuje nepřekračovat 1–4 KB na záznam. Pro velké objemy použijte šifrování souborů a uložení klíče v Keychain a samotná data v Documents.
Po jailbreaku je ochrana Keychain snížena, protože útočník získá root přístup a může přímo číst Keychain SQLite. Pro kritická data použijte dodatečné šifrování s klíčem získaným ze serveru.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také