Keychain ist ein sicherer Credential-Speicher in iOS, watchOS, macOS und tvOS, der Passwörter, Schlüssel und Zertifikate auf Hardware-Ebene verwaltet. Anders als UserDefaults werden Daten in Keychain verschlüsselt und pro App-Sandbox isoliert. Laut Apple Developer Documentation verwendet Keychain Secure-Enclave-Mechanismen und AES-256-Hardwareverschlüsselung zum Schutz vertraulicher Informationen.
Wichtigste Punkte
Keychain ist eine sichere Datenbank des Apple-Betriebssystems, die für die sichere Speicherung von Passwörtern, kryptografischen Schlüsseln, Zertifikaten und anderen vertraulichen Daten entwickelt wurde. Keychain erschien erstmals 1999 in Mac OS 8.6 und auf iOS ab der ersten SDK-Version.
Keychain löst ein grundlegendes Problem der mobilen Entwicklung: die Speicherung von Geheimnissen (Tokens, Passwörter, Verschlüsselungsschlüssel) in einem ungesicherten Dateisystem. Anders als UserDefaults oder SQLite werden Daten in Keychain verschlüsselt gespeichert und beim Schreiben auf die Festplatte automatisch verschlüsselt.
Jede iOS-App läuft in einer isolierten Sandbox und hat nur Zugriff auf ihren eigenen keychain. Der Entwickler kann jedoch den gemeinsamen Keychain-Zugriff zwischen Apps desselben Entwicklers über keychain access groups konfigurieren. Der iCloud Keychain des Benutzers synchronisiert Daten zusätzlich zwischen Geräten über Ende-zu-Ende-Verschlüsselung.
Laut Apple Security White Paper (2025) verwendet Keychain AES-256-Hardwareverschlüsselung mit einem an die eindeutige Geräte-ID (UID) gebundenen Schlüssel, wodurch Daten beim Extrahieren aus dem Gerät unzugänglich sind.
Keychain fungiert als mehrschichtiger Dienst: Die App greift auf das Security framework zu, das mit dem securityd-Daemon kommuniziert, der die verschlüsselte SQLite-Keychain-Datenbank verwaltet. Jeder Datensatz wird mit einem separaten Schlüssel verschlüsselt, und die Schlüssel selbst werden durch das Secure-Enclave-Hardwaremodul auf Geräten mit A7-Chip und neuer geschützt.
Das Security framework bietet eine C-Schnittstelle für die Arbeit mit Keychain Services. Hauptfunktionen: SecItemAdd (hinzufügen), SecItemCopyMatching (suchen), SecItemUpdate (aktualisieren) und SecItemDelete (löschen). Jeder Vorgang akzeptiert ein CFDictionaryRef-Attributwörterbuch, das den Anfragetyp beschreibt.
Daten werden nach Klassen klassifiziert: kSecClassGenericPassword (beliebiges Passwort), kSecClassInternetPassword (Internetdienst-Passwort), kSecClassCertificate (Zertifikat), kSecClassKey (kryptografischer Schlüssel) und kSecClassIdentity (Schlüssel-Zertifikat-Paar).
Beim Speichern eines Passworts erstellt die App ein Wörterbuch mit Attributen: Dienst, Konto, Zugriffsstufe, Bezeichnung. Das Security framework übergibt die Daten an den securityd-Daemon, der den Datensatz mit einem gerätegebundenen Schlüssel verschlüsselt und in der Keychain-SQLite speichert. Der Abruf funktioniert ähnlich: Abfrage nach Attributen, Suche, Entschlüsselung und Rückgabe der Daten.
Eine wichtige Besonderheit: Beim Löschen einer App löscht iOS automatisch die von dieser App erstellten Keychain-Einträge (ab iOS 10.3+). Bei einer Neuinstallation der App sind Keychain-Daten der vorherigen Installation nicht verfügbar, es sei denn, iCloud Keychain wurde verwendet.
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 unterstützt fünf Hauptdatenklassen, jede mit eigenem Attributsatz und Anwendungsbereich. Die Wahl der Klasse bestimmt, welche Suchschlüssel verfügbar sind und wie Daten verschlüsselt werden.
Die Klassen kSecClassGenericPassword und kSecClassInternetPassword sind für die Speicherung von Textpasswörtern ausgelegt. Die Internet-Version speichert zusätzlich Serverdaten: Domain, Protokoll, Port und Authentifizierungspfad. GenericPassword wird für die Speicherung beliebiger Passwörter ohne Serverbindung verwendet.
Beim Speichern eines Internet-Passworts können Sie kSecAttrServer (Domain), kSecAttrProtocol (HTTPS, FTP usw.), kSecAttrPort und kSecAttrPath angeben. Dies ermöglicht die genaue Identifizierung des Datensatzes beim automatischen Ausfüllen über AutoFill.
Die Klasse kSecClassKey speichert symmetrische (AES) und asymmetrische (RSA, EC) Schlüssel. Die Klasse kSecClassCertificate speichert X.509-Zertifikate. Die Klasse kSecClassIdentity kombiniert einen privaten Schlüssel und sein zugehöriges Zertifikat in einem Datensatz.
Für asymmetrische Schlüssel unterstützt Keychain Attribute: kSecAttrKeyType (RSA, EC), kSecAttrKeySizeInBits (2048, 256), kSecAttrIsPermanent (in Keychain speichern). Für Zertifikate: kSecAttrLabel (menschenlesbarer Name), kSecAttrSubject (DN des Eigentümers), kSecAttrIssuer (DN des Ausstellers).
| Keychain-Klasse | Zweck | Datentyp |
|---|---|---|
| kSecClassGenericPassword | App-Passwort | Data (NSString) |
| kSecClassInternetPassword | Server-Passwort | Data + Serverattribute |
| kSecClassCertificate | X.509-Zertifikat | SecCertificate |
| kSecClassKey | Kryptografischer Schlüssel | SecKey |
| kSecClassIdentity | Schlüssel + Zertifikat | SecIdentity |
Die Hauptschnittstelle für die Interaktion mit Keychain in nativem iOS-Code sind die Funktionen des Security framework. Für Swift und Objective-C steht eine einheitliche C-Schnittstelle zur Verfügung, die in praktische Funktionen eingebettet ist.
Die Funktion SecItemAdd fügt ein neues Element zur Keychain hinzu. Sie nimmt als Eingabe ein Wörterbuch mit Klasse, Daten und Attributen entgegen. Gibt den Status errSecSuccess (0) oder einen Fehlercode zurück. Die Funktion SecItemCopyMatching führt eine Suche nach Attributen durch und gibt die gefundenen Daten zurück.
Für die Suche wird das Flag kSecReturnData verwendet — bei true gibt die Funktion den Inhalt des Datensatzes zurück. Das Flag kSecMatchLimit bestimmt die Anzahl der Ergebnisse: kSecMatchLimitOne (eins) oder 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 ermöglicht das Ändern von Attributen oder Daten eines vorhandenen Datensatzes. SecItemDelete löscht alle Datensätze, die mit dem übergebenen Wörterbuch übereinstimmen. Beim Löschen ist es wichtig, genügend Attribute anzugeben, um nicht versehentlich fremde Datensätze im gemeinsamen Keychain zu löschen.
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)
}
Jeder Keychain-Datensatz hat das Attribut kSecAttrAccessible, das bestimmt, wann die Daten zum Lesen verfügbar sind. Dies ist für die Sicherheit von entscheidender Bedeutung: Eine falsche Zugriffsstufe kann Daten angreifbar machen oder sie umgekehrt bei Bedarf unzugänglich machen.
kSecAttrAccessibleWhenUnlocked — Daten sind nur verfügbar, wenn das Gerät entsperrt ist. kSecAttrAccessibleAfterFirstUnlock — verfügbar nach dem ersten Entsperren nach einem Neustart. kSecAttrAccessibleAlways — immer verfügbar (nicht empfohlen). Das Suffix ThisDeviceOnly verhindert die Datenübertragung durch Backups.
Auf Geräten mit Secure Enclave kann der Keychain-Verschlüsselungsschlüssel zusätzlich durch Biometrie geschützt werden: kSecAccessControlBiometryCurrentSet oder kSecAccessControlUserPresence. Dies fügt eine Face-ID- oder Touch-ID-Anforderung für jeden Lesevorgang hinzu.
iCloud Keychain synchronisiert Datensätze zwischen Apple-Geräten über Ende-zu-Ende-Verschlüsselung. Apple hat keinen Zugriff auf die entschlüsselten Daten. Um die Synchronisation zu aktivieren, fügen Sie das Attribut kSecAttrSynchronizable mit dem Wert kCFBooleanTrue hinzu.
Wichtig: Synchronisierte Datensätze dürfen das Attribut ThisDeviceOnly nicht enthalten, da sie auf anderen Geräten verfügbar sein müssen. Wenn alle Geräte verloren gehen, kann iCloud Keychain über einen Wiederherstellungscode oder einen iCloud-Wiederherstellungsschlüssel wiederhergestellt werden.
Verwenden Sie für Authentifizierungs-Tokens kSecAttrAccessibleWhenUnlockedThisDeviceOnly — Daten sind nur bei entsperrtem Gerät verfügbar und werden nicht in Backups kopiert. Für Zertifikate, die für Hintergrundaufgaben verfügbar sein müssen, verwenden Sie kSecAttrAccessibleAfterFirstUnlock. Verwenden Sie niemals kSecAttrAccessibleAlways für vertrauliche Daten.
Es wird empfohlen, für Daten, die keine Synchronisation benötigen, immer das Suffix ThisDeviceOnly hinzuzufügen. Dies verhindert das versehentliche Kopieren von Geheimnissen in iCloud- oder iTunes-Backups, wo sie mit Analysetools extrahiert werden könnten. Für kritische Daten kombinieren Sie die Verfügbarkeit mit kSecAccessControlUserPresence — dies fügt eine biometrische oder Passcode-Anforderung zur Entschlüsselung des Datensatzes hinzu.
Bei Verwendung von iCloud Keychain beachten Sie, dass synchronisierte Datensätze auf allen Benutzergeräten verfügbar sind: Wenn ein Angreifer Zugriff auf ein Gerät erhält, könnten die Daten auf allen Geräten gefährdet sein. Verwenden Sie für isolierte Geheimnisse ThisDeviceOnly.
Häufig gestellte Fragen
UserDefaults speichert Daten im Klartext in einer .plist-Datei, die bei der IPA-Analyse zugänglich ist. Keychain verschlüsselt jeden Datensatz separat, verwendet Hardwareverschlüsselung und unterstützt Zugriffsstufen, Biometrie und Synchronisation über iCloud.
Bei jedem Start des iOS-Simulators wird Keychain geleert. Auf einem echten Gerät löschen Sie die App — iOS entfernt alle Keychain-Einträge dieses Entwicklers. Für gezieltes Löschen rufen Sie SecItemDelete mit den entsprechenden Attributen auf.
Ja, über keychain access groups. Die Apps müssen dieselbe Team-ID im Provisioning-Profil und Berechtigungen mit denselben keychain-access-groups haben. Der Entwickler konfiguriert den gemeinsamen Zugriff in Xcode Capabilities.
Apple dokumentiert keine strikte Grenze, aber in der Praxis wird empfohlen, 1–4 KB pro Datensatz nicht zu überschreiten. Für größere Datenmengen verwenden Sie Dateiverschlüsselung und speichern den Schlüssel in Keychain, während die Daten selbst in Documents abgelegt werden.
Auf einem gejailbreakten Gerät ist der Keychain-Schutz eingeschränkt, da der Angreifer Root-Zugriff erhält und die Keychain-SQLite direkt auslesen kann. Verwenden Sie für kritische Daten zusätzliche Verschlüsselung mit einem vom Server bezogenen Schlüssel.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch