Keychain — is een beveiligde opslagplaats van inloggegevens in iOS, watchOS, macOS en tvOS die wachtwoorden, sleutels en certificaten op hardwareniveau beheert. In tegenstelling tot UserDefaults worden gegevens in Keychain versleuteld en geïsoleerd door de sandbox van de app. Volgens Apple Developer Documentation gebruikt Keychain Secure Enclave-mechanismen en hardwarematige AES-256-versleuteling om vertrouwelijke informatie te beschermen.
Belangrijkste punten
Keychain — is een beveiligde database van het Apple-besturingssysteem, ontworpen voor het veilig opslaan van wachtwoorden, cryptografische sleutels, certificaten en andere vertrouwelijke gegevens. Keychain verscheen voor het eerst in Mac OS 8.6 in 1999 en op iOS — vanaf de eerste SDK-versie.
Keychain lost een fundamenteel probleem van mobiele ontwikkeling op: het opslaan van geheimen (tokens, wachtwoorden, versleutelingssleutels) in een onbeveiligd bestandssysteem. In tegenstelling tot UserDefaults of SQLite worden gegevens in Keychain in versleutelde vorm opgeslagen en automatisch versleuteld bij het schrijven naar schijf.
Elke iOS-app werkt in een geïsoleerde sandbox en heeft alleen toegang tot zijn eigen keychain. De ontwikkelaar kan echter gedeelde toegang tot Keychain tussen apps van dezelfde ontwikkelaar configureren via keychain access groups. De iCloud Keychain-gebruiker synchroniseert bovendien gegevens tussen apparaten via end-to-end-versleuteling.
Volgens Apple Security White Paper (2025) gebruikt Keychain hardwarematige AES-256-versleuteling met een sleutel die is gekoppeld aan de unieke apparaat-ID (UID), waardoor gegevens ontoegankelijk zijn bij extractie uit het apparaat.
Keychain functioneert als een gelaagde service: de app roept Security framework aan, dat interageert met de securityd-daemon, die de versleutelde SQLite-database van Keychain beheert. Elk item wordt versleuteld met een aparte sleutel, en de sleutels zelf worden beschermd door de hardwaremodule Secure Enclave op apparaten met A7-chip en nieuwer.
Security framework biedt een C-interface voor werken met Keychain Services. Belangrijkste functies: SecItemAdd (toevoegen), SecItemCopyMatching (zoeken), SecItemUpdate (bijwerken) en SecItemDelete (verwijderen). Elke bewerking ontvangt een woordenboek van attributen CFDictionaryRef dat het type verzoek beschrijft.
Gegevens worden geclassificeerd volgens klassen: kSecClassGenericPassword (willekeurig wachtwoord), kSecClassInternetPassword (wachtwoord voor internetservice), kSecClassCertificate (certificaat), kSecClassKey (cryptografische sleutel) en kSecClassIdentity (combinatie van sleutel en certificaat).
Bij het opslaan van een wachtwoord maakt de app een woordenboek met attributen: service, account, toegangsniveau, label. Security framework stuurt de gegevens naar de securityd-daemon, die het item versleutelt met een aan het apparaat gekoppelde sleutel en opslaat in Keychain SQLite. Ophalen gebeurt op dezelfde manier: verzoek op basis van attributen, zoeken, ontsleutelen en teruggeven van gegevens.
Een belangrijke eigenschap: bij het verwijderen van de app wist iOS automatisch Keychain-items die door deze app zijn gemaakt (vanaf iOS 10.3+). Bij herinstallatie van de app zijn Keychain-gegevens van de vorige installatie ontoegankelijk, tenzij iCloud Keychain is gebruikt.
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 ondersteunt vijf hoofdklassen van gegevens, elk met zijn eigen set attributen en toepassingsgebied. De keuze van de klasse bepaalt welke zoeksleutels beschikbaar zijn en hoe gegevens worden versleuteld.
De klassen kSecClassGenericPassword en kSecClassInternetPassword zijn bedoeld voor het opslaan van tekstwachtwoorden. De internetversie slaat bovendien servergegevens op: domein, protocol, poort en authenticatiepad. GenericPassword wordt gebruikt voor het opslaan van willekeurige wachtwoorden zonder koppeling aan een server.
Bij het opslaan van een internetwachtwoord kunnen kSecAttrServer (domein), kSecAttrProtocol (HTTPS, FTP enz.), kSecAttrPort en kSecAttrPath worden opgegeven. Dit maakt nauwkeurige identificatie van het item mogelijk bij automatisch invullen via AutoFill.
Klasse kSecClassKey slaat symmetrische (AES) en asymmetrische (RSA, EC) sleutels op. Klasse kSecClassCertificate — X.509-certificaten. Klasse kSecClassIdentity combineert de privésleutel en het bijbehorende certificaat in één item.
Voor asymmetrische sleutels ondersteunt Keychain attributen: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (of opslaan in Keychain). Voor certificaten: kSecAttrLabel (mensleesbare naam), kSecAttrSubject (DN van eigenaar), kSecAttrIssuer (DN van uitgever).
| Keychain-klasse | Doel | Gegevenstype |
|---|---|---|
| kSecClassGenericPassword | App-wachtwoord | Data (NSString) |
| kSecClassInternetPassword | Serverwachtwoord | Data + serverattributen |
| kSecClassCertificate | X.509-certificaat | SecCertificate |
| kSecClassKey | Cryptografische sleutel | SecKey |
| kSecClassIdentity | Sleutel + certificaat | SecIdentity |
De belangrijkste interface voor interactie met Keychain in native iOS-code — de functies van Security framework. Voor Swift en Objective-C is één C-interface beschikbaar, verpakt in handige functies.
De functie SecItemAdd voegt een nieuw element toe aan Keychain. Invoer ontvangt een woordenboek met klasse, gegevens en attributen. Retourneert status errSecSuccess (0) of een foutcode. De functie SecItemCopyMatching voert zoeken uit op basis van attributen en retourneert gevonden gegevens.
Voor zoeken wordt de vlag kSecReturnData gebruikt — indien true retourneert de functie de inhoud van het item. De vlag kSecMatchLimit bepaalt het aantal resultaten: kSecMatchLimitOne (één) of kSecMatchLimitAll (alle).
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 maakt het mogelijk attributen of gegevens van een bestaand item te wijzigen. SecItemDelete verwijdert alle items die overeenkomen met het meegegeven woordenboek. Bij verwijderen is het belangrijk voldoende attributen op te geven om niet per ongeluk items van anderen in shared keychain te verwijderen.
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)
}
Elk Keychain-item heeft het attribuut kSecAttrAccessible, dat bepaalt wanneer gegevens beschikbaar zijn voor lezen. Dit is cruciaal voor beveiliging: een verkeerd toegangsniveau kan gegevens kwetsbaar maken of juist ontoegankelijk op het verkeerde moment.
kSecAttrAccessibleWhenUnlocked — gegevens alleen beschikbaar wanneer het apparaat is ontgrendeld. kSecAttrAccessibleAfterFirstUnlock — beschikbaar na eerste ontgrendeling na herstart. kSecAttrAccessibleAlways — altijd beschikbaar (niet aanbevolen). Postfix ThisDeviceOnly verbiedt overdracht van gegevens via back-up.
Op apparaten met Secure Enclave kan de Keychain-versleutelingssleutel extra worden beveiligd met biometrie: kSecAccessControlBiometryCurrentSet of kSecAccessControlUserPresence. Dit voegt een Face ID- of Touch ID-vereiste toe voor elke leesbewerking.
iCloud Keychain synchroniseert items tussen Apple-apparaten via end-to-end-versleuteling. Apple heeft geen toegang tot ontsleutelde gegevens. Om synchronisatie in te schakelen, voegt u het attribuut kSecAttrSynchronizable toe met waarde kCFBooleanTrue.
Belangrijk: gesynchroniseerde items kunnen het attribuut ThisDeviceOnly niet bevatten, omdat ze op andere apparaten beschikbaar moeten zijn. Bij verlies van alle apparaten wordt iCloud Keychain hersteld via een herstelcode of iCloud-back-upsleutel.
Gebruik voor authenticatietokens kSecAttrAccessibleWhenUnlockedThisDeviceOnly — gegevens alleen beschikbaar op ontgrendeld apparaat en niet gekopieerd naar back-up. Voor certificaten die beschikbaar moeten zijn voor achtergrondtaken, gebruik kSecAttrAccessibleAfterFirstUnlock. Gebruik nooit kSecAttrAccessibleAlways voor vertrouwelijke gegevens.
Het wordt aanbevolen altijd de postfix ThisDeviceOnly toe te voegen voor gegevens die geen synchronisatie vereisen. Dit voorkomt het per ongeluk kopiëren van geheimen naar iCloud of iTunes-back-up, waar ze kunnen worden geëxtraheerd met analysetools. Voor kritieke gegevens combineert u beschikbaarheid met kSecAccessControlUserPresence — dit voegt een biometrie- of codevereiste toe voor ontsleuteling van het item.
Houd bij gebruik van iCloud Keychain rekening mee dat gesynchroniseerde items beschikbaar zijn op alle apparaten van de gebruiker: als een aanvaller toegang krijgt tot één apparaat, kunnen gegevens op alle apparaten worden gecompromitteerd. Gebruik ThisDeviceOnly voor geïsoleerde geheimen.
Veelgestelde vragen
UserDefaults slaat gegevens in open vorm op in een .plist-bestand, toegankelijk bij IPA-analyse. Keychain versleutelt elk item afzonderlijk, gebruikt hardwareversleuteling en ondersteunt toegangsniveaus, biometrie en synchronisatie via iCloud.
Bij elke start op de iOS-simulator wordt Keychain gewist. Op een echt apparaat verwijdert u de app — iOS verwijdert alle Keychain-items van deze ontwikkelaar. Voor selectief wissen roept u SecItemDelete aan met de juiste attributen.
Ja, via keychain access groups. Apps moeten dezelfde team-ID in de handtekening hebben en entitlements met dezelfde keychain-access-groups. De ontwikkelaar configureert gedeelde toegang in Xcode Capabilities.
Apple documenteert geen strikte limiet, maar in de praktijk wordt aanbevolen niet meer dan 1–4 KB per item te gebruiken. Voor grote volumes gebruikt u bestandsversleuteling en opslag van de sleutel in Keychain, en de gegevens zelf in Documents.
Na jailbreak neemt de bescherming van Keychain af, omdat de aanvaller root-toegang krijgt en Keychain SQLite direct kan lezen. Gebruik voor kritieke gegevens extra versleuteling met een van de server verkregen sleutel.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook