Blog

Sichern Sie Ihre App mit verschlüsselten Kerndaten

Aktualisiert Oktober 21, 2025
7 Minuten

Es stimmt, dass Apple die Privatsphäre der Benutzer sehr am Herzen liegt. Seit iOS 8.3 ist es unmöglich, auf beliebige Daten in der Sandbox einer Anwendung zuzugreifen. Außerdem können Entwickler die Option "Datenschutz" für ihre App aktivieren, die die Sandbox verschlüsselt, wenn das Gerät mit einem Passcode gesperrt ist. Nichtsdestotrotz würde ein zusätzlicher Schutz nicht schaden, wenn er nicht zu viel Arbeit bedeutet.

Core Data ist eine beliebte Wahl für die Implementierung der Datenpersistenz in iOS- und OS X-Anwendungen. In der Regel verwendet es eine eingebettete SQLite-Datenbank. Wir könnten unter anderem versuchen, sie zu verschlüsseln. Das mag unter iOS übertrieben erscheinen, da die Sandbox der Anwendung für Dritte nicht zugänglich ist. Dennoch kann das Gerät gejailbroken sein, das Betriebssystem kann unveröffentlichte Sicherheitslücken haben oder wir wollen die Datenbank vielleicht irgendwo in der Cloud sichern. In solchen Fällen kann der zusätzliche Schutz nützlich sein. Und dann ist da natürlich noch OS X, wo die Daten der Anwendungen offen liegen.

Wenn Sie die Sicherheit Ihrer Anwendung verbessern möchten und auch Core Data verwenden, können Sie encrypted-core-data ausprobieren, eine Open-Source-Bibliothek, die den standardmäßigen Datenbankspeicher ersetzt. Encrypted Core Data verwendet intern SQLCipher, das eine transparente Verschlüsselung der gesamten Datenbank ermöglicht.

Wie man integriert

Das Einrichten einer verschlüsselten Datenbank ist ganz einfach. Sie müssen lediglich die Bibliothek zum Projekt hinzufügen und einige Werte bei der Einrichtung von Core Data ändern.

  1. Fügen Sie "EncryptedCoreData" über CocoaPods zu Ihrem Projekt hinzu:
    pod 'EncryptedCoreData'
  2. Finden Sie den Aufruf addPersistentStoreWithType in Ihrem Code. Fügen Sie den Optionen eine Passphrase hinzu (idealerweise im Schlüsselbund gespeichert oder über eine sichere Verbindung vom Backend bezogen) und ändern Sie den Speichertyp in EncryptedStoreType:
    let options = [EncryptedStorePassphraseKey : "Schlüssel"]
    try coordinator.addPersistentStoreWithType(EncryptedStoreType,  
    Konfiguration: nil, URL: url, Optionen: Optionen)

Zu diesem Zeitpunkt ist die Anwendung so konfiguriert, dass sie verschlüsseltes Sqlite verwendet, mit dem wichtigen Vorbehalt, dass eine Migration von Standard zu verschlüsselt (und umgekehrt) nicht unterstützt wird. Encrypted-core-data verwendet ein anderes Benennungsschema für Zeilen und Tabellen, so dass es nicht so einfach ist, eine bestehende Datenbank zu verschlüsseln. In diesem Fall besteht die einzige Möglichkeit darin, die Migration entweder manuell oder gar nicht durchzuführen (wenn die App noch nicht freigegeben wurde).

Leistung

Es ist verständlich, dass das Verschlüsseln von Daten im laufenden Betrieb mehr CPU-Zeit in Anspruch nimmt, wodurch Core Data-bezogene Operationen langsamer werden. Das bedeutet auch einen höheren Energieverbrauch und so weiter. Um das zu testen, habe ich ein paar Benchmarks erstellt, die genau die gleichen Operationen auf Standard- und verschlüsseltem Speicher durchführen und die Ergebnisse vergleichen.

Hinweis zu den Tests

  • Alle Messungen sind in Millisekunden angegeben.
  • Die Tests wurden zweimal durchgeführt, einmal mit einer kleineren Datenbank (Diagramme auf der linken Seite, ca. 8000 Objekte) und einmal mit einer größeren (Diagramme auf der rechten Seite, ca. 32000 Objekte).
  • Bei Diagrammen ist der kürzere Balken besser (die Operation wird schneller ausgeführt).
  • Das für diese Tests verwendete Schema ist ein einfaches Modell eines Blogs, in dem Benutzer Beiträge und Kommentare veröffentlichen können. 1-1
  • Bei der Migration wurde eine Klasse gelöscht, eine andere hinzugefügt und Eigenschaften hinzugefügt und entfernt.
  • Die Tests der Diagramme wurden auf dem iPhone 6 und dem iPhone 5s durchgeführt, beide mit iOS 9.
  • Es wurden die neuesten verschlüsselten Kerndaten aus einem Master-Zweig verwendet.

Erstellen von Datenbankobjekten

Bei diesem Test wurde eine große Anzahl von Objekten in die Datenbank eingefügt, dann geändert und anschließend gelöscht (wobei zwischen den einzelnen Aktionen gespeichert wurde).

Kleine Anzahl - iPhone 6Große Anzahl - iPhone 6
2-23-2
Kleine Anzahl - iPhone 5sGroße Anzahl - iPhone 5s
4-35-1

Verschlüsselte Kerndaten schneiden deutlich schlechter ab, insbesondere bei kleineren Datensätzen. Das ist vielleicht kein Problem, wenn Ihre Anwendung die Datenbank nicht allzu sehr verändert oder nur wenige Objekte gleichzeitig geändert werden. Andernfalls kann die Wartezeit für den Benutzer ziemlich spürbar sein, insbesondere wenn den Änderungen Anfragen an das Backend vorausgehen.

Objekte abrufen

Ein weiterer Test umfasste die Durchführung von Abfragen in der Datenbank mit unterschiedlichem Schwierigkeitsgrad und der Anzahl der abgerufenen Objekte.

Name

Prädikat

Anzahl(klein)

Anzahl(groß)

lange Abfrage, kleines Ergebnis
Inhalt wie 'test'  
AND author.name enthält 'john2'  
UND Datum  >= %@  
AND author.email enthält [cd] '@'
118778
lange Abfrage, großes Ergebnis
Inhalt wie 'test'  
AND author.name enthält 'john'  
UND Datum  >= %@  
AND author.email enthält [cd] '@'
201816005
Abfrage zählen
Kommentare.@Zahl  >= %@
2020
Kombinierter UND-Vergleich
Datum  >= %@
AND author.name enthält 'john'
201816006
Datumsvergleich
Datum  >= %@
201816006
Text-Vergleich
autor.name wie 'john4'
2001600
alle holen
TRUEPREDICATE
40003200

Hier sind die Ergebnisse:

Kleine Anzahl - iPhone 6Große Anzahl - iPhone 6
6-27
Kleine Anzahl - iPhone 5sGroße Anzahl - iPhone 5s
89

Insgesamt schien encrypted-core-data ziemlich gut abzuschneiden, in einigen Fällen sogar besser als Apples Speicher. Eine Überraschung war das Ergebnis für die Abrufanforderung mit der Anzahl (d.h. Abruf aller Benutzer, die mehr als 5 Kommentare geschrieben haben). Es scheint, dass SQLCipher für diese Aufgabe schlecht optimiert ist und vielleicht mehr Daten als nötig entschlüsselt. Andererseits dauerte eine lange Abfrage mit einem kleinen Ergebnis und Textvergleich auf dem ursprünglichen SQLite-Speicher länger.

Es gibt ein weiteres Problem, das in der Tabelle nicht zu sehen ist: NSSQLiteStore holt alle skalaren Eigenschaften der geholten Objekte, während encrypted-core-data nur deren Bezeichner holt. Dies führt zu enormen Leistungseinbußen beim Lesen der abgerufenen Objekte. Hier ist ein Beispiel:

let result = try! stack.context.executeFetchRequest(request) as! [Kommentar] 
for kommentar in ergebnis {
  _ = Kommentar.Inhalt
}

Abrufen von Objekten und Lesen von Eigenschaften

 

Kleine Anzahl - iPhone 6Große Anzahl - iPhone 6
1011
Kleine Anzahl - iPhone 5sGroße Anzahl - iPhone 5s
1213

Bei verschlüsseltem Speicher gibt es für jedes Objekt, auf das Sie zugreifen, eine zusätzliche SQL-Abfrage. Je mehr Objekte also abgerufen und gelesen werden, desto mehr Zeit wird benötigt. Besonders deutlich wird dies bei einer Abfrage, die alle Objekte aus der Datenbank abruft. Zumindest werden die Daten nicht erneut abgerufen, wenn wir eine andere Eigenschaft desselben Objekts überprüfen möchten.

Aggregat-Funktionen

Kleine Anzahl - iPhone 6Große Anzahl - iPhone 6
1415
Kleine Anzahl - iPhone 5sGroße Anzahl - iPhone 5s
1617

Ein einziger Wert (wie Durchschnitt, Anzahl usw.) wurde aus allen vorhandenen Objekten berechnet. Die Ergebnisse sind vergleichbar. Überraschenderweise war das ursprüngliche SQLite auf dem iPhone 5s etwas schneller als EncryptedStore, aber auf dem iPhone 6 etwas langsamer.

Migration

Kleine Anzahl - iPhone 6Große Anzahl - iPhone 6
1819
Kleine Anzahl - iPhone 5sGroße Anzahl - iPhone 5s
2021

Schließlich habe ich die Zeit gemessen, die für eine einfache, automatische Migration benötigt wird. Encrypted Core Data schnitt bei einem kleinen Datensatz ziemlich gut ab, bei einem größeren jedoch nur mäßig.

Leider wird eine kompliziertere Migration (wie die Verwendung einer benutzerdefinierten Mapping-Datei) derzeit nicht unterstützt.

Fehlende Funktionen und Bugs

Bei Tests habe ich festgestellt, dass einige Dinge nicht unterstützt werden oder nicht richtig funktionieren:

  • Unterstützung von Unterabfragen
  • Kundenspezifische Migration (nur automatische Migration funktioniert)
  • Externer Speicher für große Binärdateien
  • Vorausschauende Protokollierung
  • (#240) String-Vergleichsoperatoren
  • (#241) einige Aggregatfunktionen - Durchschnitt, Summe, etc.
  • Abfrage mit verschachtelter Zählung, d.h. comments.@count > 5 funktioniert , aber author.comments.@count > 5 funktioniert nicht

Werkzeuge

Im Folgenden finden Sie einige Tools zur Verwaltung von SQLCipher-Datenbanken, die verschlüsselte Kerndaten problemlos unterstützen:

DB Browser für SQLite. Open-Source-Datenbankmanager, bietet die Möglichkeit, Tabellen und gespeicherte Daten einzusehen. Die Eingabe eines Passworts ist erforderlich, um verschlüsselte Datenbanken einzusehen. SQLCipher-Unterstützung ist als separater binärer Download verfügbar.

SQLiteManager. Ein ähnliches, aber proprietäres Tool. Wird von den Schöpfern von SQLCipher beworben.

Zusammenfassung

Insgesamt ist es schwer zu sagen, ob Encrypted Core Data eine gute Wahl für Ihre Anwendung ist. Die Verwendung würde definitiv einige Abstriche bei der Benutzerfreundlichkeit oder der Entwicklungsgeschwindigkeit erfordern.

Die Leistungsprobleme mögen zwar besorgniserregend sein, aber fehlende Funktionen sind nicht so entscheidend. Ich ermutige Sie, die Bibliothek auszuprobieren und vielleicht einen Pull Request für Dinge einzureichen, die Sie benötigen.

Contact

Let’s discuss how we can support your journey.