Sichern von iOS-Daten in Ruhe Schutz der Benutzerdaten

Dies ist der erste von drei Artikeln zum Sichern von Benutzerdaten im Ruhezustand. In diesem Beitrag beginnen wir mit den Grundlagen zum Schutz von Daten unter iOS, sodass Sie die aktuellen bewährten Methoden zum sicheren Speichern von Daten mit Swift kennen lernen können.

Jede App, die die Daten des Benutzers speichert, muss für die Sicherheit und den Datenschutz dieser Daten sorgen. Wie wir kürzlich bei Datenschutzverletzungen gesehen haben, kann es sehr schwerwiegende Folgen haben, wenn die gespeicherten Daten Ihrer Benutzer nicht geschützt werden. In diesem Lernprogramm lernen Sie einige bewährte Methoden zum Schutz Ihrer Benutzerdaten kennen.

Berechtigungen

Bevor wir Ihre benutzerdefinierten Daten speichern können, werfen wir einen Blick auf Daten, die von System-Apps gemeinsam genutzt werden können. 

Bei vielen iOS-Versionen mussten App-Berechtigungen angefordert werden, um einige der privaten Daten des Benutzers außerhalb der App zu verwenden und zu speichern, z. B. beim Speichern und Laden von Bildern in die Fotobibliothek. Ab iOS 10 müssen Sie bei allen APIs, die auf die privaten Daten des Benutzers zugreifen, diesen Zugriff vorab in Ihrem Projekt angeben info.plist Datei. 

Es gibt viele Frameworks, die auf Daten außerhalb Ihrer App zugreifen können, und jedes Framework verfügt über einen entsprechenden Datenschutzschlüssel.

  • Bluetooth-Freigabe: NSBluetoothPeripheralUsageDescription
  • Kalender: NSCalendarsUsageDescription
  • CallKit: NSVoIPUsageDescription
  • Kamera: NSCameraUsageDescription
  • Kontakte: NSContactsUsageDescription
  • Gesundheit: NSHealthShareUsageBeschreibung, NSHealthUpdateUsageDescription
  • HomeKit: NSHomeKitUsageDescription
  • Ort: NSLocationAlwaysUsageDescription, NSLocationUsageDescription, NSLocationWhenInUseUsageDescription
  • Medienbibliothek: NSAppleMusicUsageDescription
  • Mikrofon: NSMicrophoneUsageDescription
  • Bewegung: NSMotionUsageDescription
  • Fotos: NSPhotoLibraryUsageDescription
  • Erinnerungen: NSRemindersUsageDescription
  • Spracherkennung: NSSpeechRecognitionUsageDescription
  • SiriKit: NSSiriUsageBeschreibung
  • TV-Anbieter: NSVideoSubscriberAccountUsageDescription

Hier ist zum Beispiel ein Eintrag in info.plist um zuzulassen, dass Ihre App Werte in den Kalender lädt und speichert.

NSCalendarsUsageDescription Anzeigen und Hinzufügen von Ereignissen zu Ihrem Kalender

Wenn eine Verwendungsbeschreibung fehlt, wenn die API versucht, auf die Daten zuzugreifen, stürzt die App einfach ab.

Die Datenschutz-API

Bei allen Benutzerdaten, die in der App enthalten sind, sollten Sie zuerst darüber nachdenken, ob Sie die Informationen speichern müssen und welche Daten für die App wesentlich sind. Bewahren Sie so viele dieser wichtigen Daten im Arbeitsspeicher statt im Dateispeicher auf. Dies ist besonders wichtig für personenbezogene Daten. 

Wenn Sie jedoch Daten speichern müssen, empfiehlt es sich, den Datenschutz von Apple zu aktivieren.

Der Datenschutz verschlüsselt den Inhalt des App-Containers. Es setzt voraus, dass der Benutzer einen Passcode besitzt, und somit hängt die Sicherheit der Verschlüsselung von der Stärke des Passcodes ab. Mit Touch ID und der in iOS 10.3 eingeführten aktualisierten Dateisystemverschlüsselung hat das Datenschutzsystem viele Verbesserungen erfahren. Sie können den Datenschutz in Ihrer App durch Aktivieren aktivieren Datenschutz in dem Fähigkeiten Abschnitt Ihrer Projektdatei. Dadurch werden Ihr Bereitstellungsprofil und die Berechtigungsdatei mit der Datenschutzfunktion aktualisiert. Der Datenschutz bietet vier Schutzstufen, die durch das dargestellt werden FileProtectionType Struktur:

  • keiner: kein Schutz.
  • Komplett: Daten sind nicht verfügbar, während das Gerät gesperrt ist. Dies ist die empfohlene Einstellung für die meisten Anwendungen.
  • completeUnlessOpen: Auf Daten kann zugegriffen werden, wenn das Gerät nicht gesperrt ist, und es ist weiterhin verfügbar, bis die Datei geschlossen wird, selbst wenn der Benutzer das Gerät sperrt. Dateien können auch erstellt werden, wenn das Gerät gesperrt ist. Diese Option ist nützlich, wenn Sie eine zu öffnende Datei öffnen und den Vorgang fortsetzen müssen, auch wenn der Benutzer die App in den Hintergrund stellt und das Gerät sperrt. Ein Beispiel könnte ein Job sein, der eine Datei auf einen Server hochlädt.
  • completeUntilFirstUserAuthentication: Wenn das Gerät gestartet wird, kann auf Dateien nicht zugegriffen werden, bis der Benutzer das Gerät zum ersten Mal entsperrt. Danach sind Dateien verfügbar, auch wenn das Gerät wieder gesperrt ist. Die Option eignet sich für Dateien, auf die später im Hintergrund zugegriffen werden muss, wenn das Gerät gesperrt ist, z. B. während eines Hintergrundabrufjobs.

Komplett ist die Standardstufe. Um Abstürze zu vermeiden, wenn Ihr Code versucht, auf gesperrte Daten zuzugreifen, können Sie sich für Benachrichtigungen über registrieren UIApplicationProtectedDataDidBecomeAvailable und UIApplicationProtectedDataWillBecomeUnavailable um herauszufinden, wann die Daten verfügbar sind.

NotificationCenter.default.addObserver (forName: .UIApplicationProtectedDataDidBecomeAvailable, Objekt: nil, Warteschlange: OperationQueue.main, mit: (notification) in //…) NotificationCenter.default.addObserver (forName: .UIApplicationProtectedDataWillBacOnachArchnach OperationQueue.main, mit: (Benachrichtigung) in //…)

Zusätzlich können Sie auch das überprüfen UIApplication.shared.isProtectedDataAvailable Flagge.

Beachten Sie bei der Aktivierung des Datenschutzes Folgendes: Wenn Sie Hintergrunddienste wie Hintergrundabruf verwenden, muss dieser Code möglicherweise im Hintergrund auf Ihre Daten zugreifen, wenn das Gerät gesperrt ist. Für diese Dateien müssen Sie eine Schutzstufe von festlegen completeUntilFirstUserAuthentication. Sie können die Schutzstufe jeder Datei individuell festlegen, wenn Sie Dateien und Verzeichnisse mithilfe von erstellen Dateimanager Klasse.

let ok = FileManager.default.createFile (atPath: somePath, Inhalt: nil, Attribute: [FileAttributeKey.protectionKey.rawValue: FileProtectionType.complete]) do try FileManager.default.createDirectory (atPath: somePath, withIntermediateDirectories: true; [FileAttributeKey.protectionKey.rawValue: FileProtectionType.complete]) catch print (error)

Sie können auch die Schutzstufe einstellen, wenn Sie in eine Datei schreiben. Das Daten object verfügt über eine Methode, die seine Daten in eine Datei schreiben kann, und Sie können die Schutzstufe festlegen, wenn Sie diese Methode aufrufen.

let data = Data.init () let fileURL = versuchen! FileManager.default.url (für: .documentDirectory, in: .userDomainMask, properFor: nil, create: false) .appendingPathComponent ("somedata.dat") do try data.write (in: fileURL, Optionen: ([.atomic .completeFileProtection])) catch print (error)

Sie können auch die Schutzstufe einstellen, wenn Sie Ihr Kerndatenmodell einrichten.

let storeURL = docURL? .appendingPathComponent ("Model.sqlite") let storeOptions: [AnyHashable: Any] = [NSPersistentStoreFileProtectionKey: FileProtectionType.complete] do try coordinator.addPersistentStore (ofType: NSSQLiteStoreType, configurationName: ohne : storeOptions) catch print (error)

Verwenden Sie zum Ändern der Schutzstufe einer vorhandenen Datei Folgendes:

do try FileManager.default.setAttributes ([FileAttributeKey.protectionKey: FileProtectionType.complete], ofItemAtPath: path) catch print (error)

Datenintegrität

Zum Schutz Ihrer gespeicherten Daten gehört auch die Überprüfung der Integrität. Es ist empfehlenswert, den Daten, die Sie aus dem Speicher laden, nicht blind zu vertrauen. es kann versehentlich oder böswillig geändert worden sein. Das NSSecureCoding Protokoll kann verwendet werden, um Ihre Datenobjekte sicher aus dem Speicher zu laden und zu speichern. Dadurch wird sichergestellt, dass die geladenen Objekte die erwarteten Daten enthalten. Wenn Sie Ihr eigenes Objekt speichern, können Sie das sichere Codierungsprotokoll in Ihrer Klasse einhalten.

Klasse ArchiveExample: NSObject, NSSecureCoding var stringExample: String?… 

Die Klasse muss von vererbt werden NSObject. Um die sichere Codierung zu aktivieren, überschreiben Sie die supportSecureCoding Protokollmethode.

static var unterstütztSecureCoding: Bool get return true

Wenn Ihr benutzerdefiniertes Objekt mit deserialisiert wird init? (Coder aDecoder: NSCoder), das decodeObject (forKey :) Methode sollte durch ersetzt werden decodeObject (of: forKey :), Dadurch wird sichergestellt, dass die richtigen Objekttypen aus dem Speicher ausgepackt werden.

erforderlicher init (Coder aDecoder: NSCoder) stringExample = aDecoder.decodeObject (von: NSString.self, forKey: "string_example") als String?  func encode (mit aCoder: NSCoder) aCoder.encode (stringExample, forKey: "string_example")

Wenn Sie verwenden NSKeyedUnarchiver Um Daten aus dem Speicher zu laden, stellen Sie sicher, dass RequiresSecureCoding Eigentum.

Klasse func loadFromSavedData () -> ArchiveExample? var object: ArchiveExample? = nil let path = NSSearchPathForDirectoriesInDomains (.documentDirectory, .userDomainMask, true) [0] als String let url = NSURL (fileURLWithPath: path) let fileURL = url.appendingPathComponent ("ArchiveExample.plist") : (fileURL? .path)!) do let data = try Data.init (contentsOf: fileURL!). Lassen Sie unarchiver = NSKeyedUnarchiver.init (forReadingWith: data) unarchiver.requiresSecureCoding = true object = unarchiver.decodeObject (von: ArchiveExample) .selbst, fürSchlüssel: NSKeyedArchiveRootObjectKey) unarchiver.finishDecoding () catch print (error) return object; 

Wenn Sie die sichere Codierung für Ihre Sicherungsoperationen aktivieren, können Sie nicht versehentlich ein Objekt archivieren, das nicht dem sicheren Codierungsprotokoll entspricht.

func save () let path = NSSearchPathForDirectoriesInDomains (.documentDirectory, .userDomainMask, true) [0] als String let url = NSURL (fileURWithPath: path) let filePath = url.appendingPathComponent ("ArchiveExample.plist") = NSMutableData.init () let archiver = NSKeyedArchiver.init (forWritingWith: data) archiver.requiresSecureCoding = true archiver.encode (self, forKey: NSKeyedArchiveRootObjectKey) ] do try data.write (toFile: filePath !, Optionen: Optionen) catch print (error)

Darüber hinaus NSSecureCoding, Es ist immer gut, Ihre eigenen Datenvalidierungsprüfungen zu implementieren, wenn Sie ein Archiv entpacken oder eine beliebige Eingabe erhalten.

Datenpfade

Da sich iOS ständig weiterentwickelt, gibt es immer neue Funktionen, die möglicherweise gespeicherte Daten verlieren. Ab iOS 9 können Sie Ihre Inhalte in der Spotlight-Suche indexieren lassen. Unter iOS 10 können Sie Ihre Inhalte Widgets wie dem Heute-Widget, das auf dem Sperrbildschirm angezeigt wird, anzeigen. Seien Sie vorsichtig, wenn Sie Ihre Inhalte mit diesen neuen Funktionen anzeigen möchten. Sie könnten am Ende mehr freigeben als geplant!

iOS 10 fügt außerdem eine neue Übergabefunktion hinzu, bei der die kopierten Pasteboard-Daten automatisch zwischen Geräten freigegeben werden. Achten Sie auch hier darauf, keine sensiblen Daten im Pasteboard für Handoff verfügbar zu machen. Sie können dies tun, indem Sie den sensiblen Inhalt als kennzeichnen nur lokal. Sie können auch ein Verfallsdatum und eine Uhrzeit für die Daten festlegen.

let stringToCopy = "kopiere mich ins Pasteboard" let pasteboard = UIPasteboard.general if #available (iOS 10, *) let tomorrow = Date (). addTimeInterval (60 * 60 * 24) stringToCopy]], Optionen: [UIPasteboardOption.localOnly: true, UIPasteboardOption.expirationDate: tomorrow]) else pasteboard.string = stringToCopy

Dateien, die im Speicher des Geräts gespeichert sind, können automatisch entweder in iTunes oder in iCloud gesichert werden. Auch wenn Backups verschlüsselt werden können, ist es eine gute Idee, vertrauliche Dateien auszuschließen, die das Gerät nicht verlassen müssen. Dies kann durch die Einstellung von gemacht werden isExcludedFromBackup Fahne in der Datei.

let path: String =… var url = URL (fileURLWithPath: path) do var resourceValues ​​= URLResourceValues ​​() // oder wenn Sie das Flag zuerst überprüfen möchten: // var resourceValues ​​= versuchen Sie url.resourceValues ​​(forKeys: [.isExcludedFromBackupKey) ]) resourceValues.isExcludedFromBackup = true; try url.setResourceValues ​​(resourceValues) catch print (error)

Die Animation, die auftritt, wenn eine App in den Hintergrund gestellt wird, wird durch iOS erstellt, das einen Screenshot Ihrer App erstellt, die dann für die Animation verwendet wird. Wenn Sie sich die Liste der geöffneten Apps auf dem App-Switcher ansehen, wird dieser Screenshot auch dort verwendet. Der Screenshot wird auf dem Gerät gespeichert. 

Es empfiehlt sich, alle Ansichten zu verbergen, die sensible Daten enthalten, damit die Daten nicht im Screenshot erfasst werden. Richten Sie dazu eine Benachrichtigung ein, wenn die Anwendung in den Hintergrund wechselt, und legen Sie die ausgeblendete Eigenschaft für die Elemente der Benutzeroberfläche fest, die Sie ausschließen möchten. Sie werden ausgeblendet, bevor iOS den Bildschirm erfasst. Wenn Sie dann in den Vordergrund kommen, können Sie die Elemente der Benutzeroberfläche wieder einblenden.

NotificationCenter.default.addObserver (self, Selector: #selector (didEnterBackground), Name: .UIApplicationDidEnterBackground, object: nil) NotificationCenter.default.addObserver (self, Selector: #selector (willEnterForeground), Name: .UIApplicationWillTree.

Entfernen Sie Ihre Benachrichtigungen, wenn die Ansicht verschwindet.

NotificationCenter.default.removeObserver (self, name: .UIApplicationDidEnterBackground, object: nil) NotificationCenter.default.removeObserver (self, name: .UIApplicationWillEnterForeground, object: nil)

Ihre App verfügt auch über einen Tastaturcache für Textfelder, für die die automatische Korrektur aktiviert ist. Text, den der Benutzer zusammen mit neu gelernten Wörtern eingibt, wird im Cache gespeichert, sodass verschiedene Wörter abgerufen werden können, die der Benutzer zuvor in Ihre Anwendung eingegeben hat. Der Tastatur-Cache kann nur deaktiviert werden, indem die Option zur automatischen Korrektur deaktiviert wird.

textField.autocorrectionType = UITextAutocorrectionType.no

Sie sollten Kennwortfelder als sichere Texteingabe markieren. Sichere Textfelder zeigen weder das Kennwort noch den Tastaturcache an.

textField.isSecureTextEntry = true

Debug-Protokolle werden in einer Datei gespeichert und können für Produktions-Builds Ihrer App abgerufen werden. Achten Sie auch beim Codieren und Debuggen Ihrer App darauf, keine sensiblen Informationen wie Kennwörter und Schlüssel in der Konsole zu protokollieren. Sie können vergessen, diese Informationen aus den Protokollen zu entfernen, bevor Sie den Code an den App Store senden. Beim Debuggen ist es sicherer, einen Haltepunkt zu verwenden, um sensible Variablen anzuzeigen.

Netzwerkverbindungen können auch im Speicher zwischengespeichert werden. Weitere Informationen zum Entfernen und Deaktivieren des Netzwerkcaches finden Sie im Artikel Sichern der Kommunikation unter iOS.

Daten zerstören

Sie wissen möglicherweise bereits, dass beim Löschen einer Datei auf einem Computer die Datei selbst oft nicht entfernt wird. Nur die Referenz für die Datei wird entfernt. Um die Datei tatsächlich zu entfernen, können Sie sie vor dem Entfernen mit zufälligen Daten überschreiben. 

Die Umstellung auf Solid-State-Laufwerke hat es schwer gemacht, die Zerstörung der Daten zu garantieren, und der beste Weg, um Daten sicher zu löschen, ist umstritten. Dieses Lernprogramm wäre jedoch nicht vollständig ohne ein Beispiel, wie Daten aus dem Speicher gelöscht werden. Aufgrund einiger anderer Debatten über das Swift-Optimierungsprogramm, und weil wir hoffen, dass jedes Byte der Datei tatsächlich überschrieben wird, implementieren wir diese Funktion in C. 

Die folgende Implementierung kann in einer .c-Datei enthalten sein. Sie müssen die Funktionsdefinition oder die Datei, die die Funktion enthält, Ihrem Bridging-Header hinzufügen, um die Funktion von Swift verwenden zu können. Sie können diese Funktion dann direkt vor den Orten aufrufen, an denen Sie sie verwenden Dateimanager's Datei löschen Methoden. Möglicherweise möchten Sie die in diesem und den kommenden Tutorials beschriebenen Best Practices in einem App-Update implementieren. Sie können dann die vorherigen ungeschützten Daten während der Migration löschen.

#einführen  #einführen  #einführen  #einführen  #einführen  #einführen  #define MY_MIN (a, b) (((a) < (b)) ? (a) : (b)) int SecureWipeFile(const char *filePath)  int lastStatus = -1; for (int pass = 1; pass < 4; pass++)  //setup local vars int fileHandleInt = open(filePath, O_RDWR); struct stat stats; unsigned char charBuffer[1024]; //if can open file if (fileHandleInt >= 0) // Dateideskriptoren erhalten int result = fstat (fileHandleInt, & stats); if (result == 0) switch (pass) // Die Implementierung des DOD 5220.22-M besagt, dass wir zuerst mit drei Durchläufen mit 10101010, 01010101 überschreiben und dann mit dem zufälligen Datenfall 1: // mit 10101010-Memset überschreiben (charBuffer, 0x55, sizeof (charBuffer)); brechen; case 2: // schreibe mit 01010101 memset (charBuffer, 0xAA, sizeof (charBuffer)); brechen; Fall 3: // Überschreiben mit arc4random für (unsigned long i = 0; i < sizeof(charBuffer); ++i)  charBuffer[i] = arc4random() % 255;  break; default: //at least write over with random data for (unsigned long i = 0; i < sizeof(charBuffer); ++i)  charBuffer[i] = arc4random() % 255;  break;  //get file size in bytes off_t fileSizeInBytes = stats.st_size; //rewrite every byte of the file ssize_t numberOfBytesWritten; for ( ; fileSizeInBytes; fileSizeInBytes -= numberOfBytesWritten)  //write bytes from the buffer into the file numberOfBytesWritten = write(fileHandleInt, charBuffer, MY_MIN((size_t)fileSizeInBytes, sizeof(charBuffer)));  //close the file lastStatus = close(fileHandleInt);    return lastStatus; 

Fazit

In diesem Artikel haben Sie erfahren, wie Sie Berechtigungen für die Daten festlegen, auf die Ihre App Zugriff hat, und wie Sie den grundlegenden Schutz und die Integrität von Dateien gewährleisten. Wir haben auch nach Möglichkeiten gesucht, wie Benutzerdaten aus Ihrer App versehentlich verlorengehen könnten. Ihre Benutzer vertrauen Ihnen, um ihre Daten zu schützen. Befolgen Sie diese bewährten Methoden, um dieses Vertrauen zurückzuzahlen.

Während Sie hier sind, lesen Sie einige unserer anderen Beiträge zur iOS-App-Entwicklung!