Sichern und Verschlüsseln von Daten auf iOS

Unabhängig davon, ob Sie eine mobile Anwendung oder einen Web-Service erstellen, ist es wichtig, sensible Daten zu schützen, und Sicherheit ist zu einem wesentlichen Bestandteil jedes Softwareprodukts geworden. In diesem Lernprogramm werde ich Ihnen zeigen, wie Sie Benutzeranmeldeinformationen mithilfe des Schlüsselbunds der Anwendung sicher speichern. Wir werden uns mit dem Ver- und Entschlüsseln von Benutzerdaten mithilfe einer Drittanbieter-Bibliothek befassen.


Einführung

In diesem Tutorial werde ich Ihnen zeigen, wie Sie sensible Daten auf der iOS-Plattform schützen. Vertrauliche Daten können Anmeldeinformationen eines Benutzers oder Kreditkartendaten sein. Die Art der Daten ist nicht so wichtig. In diesem Lernprogramm verwenden wir den iOS-Schlüsselbund und die symmetrische Verschlüsselung, um die Daten des Benutzers sicher zu speichern. Bevor wir uns mit den wichtigsten Details befassen, möchte ich Ihnen einen Überblick darüber geben, was wir in diesem Tutorial tun werden.

Obwohl sich dieses Tutorial auf iOS konzentriert, können die Konzepte und Techniken auch unter OS X verwendet werden.

iOS-Schlüsselbund

Unter iOS und OS X ist ein Schlüsselbund ein verschlüsselter Container zum Speichern von Kennwörtern und anderen Daten, die gesichert werden müssen. Unter OS X ist es möglich, den Schlüsselbundzugriff auf bestimmte Benutzer oder Anwendungen zu beschränken. Unter iOS hat jede Anwendung jedoch einen eigenen Schlüsselbund, auf den nur die Anwendung Zugriff hat. Dadurch wird sichergestellt, dass die im Schlüsselbund gespeicherten Daten für Dritte sicher und nicht zugänglich sind.

Beachten Sie, dass der Schlüsselbund nur zum Speichern kleiner Daten wie Passwörter verwendet werden sollte. Mit diesem Artikel hoffe ich, Sie davon zu überzeugen, wie wichtig es ist, den Schlüsselbund unter iOS und OS X zu verwenden, anstatt beispielsweise die Benutzer-Standarddatenbank der Anwendung, die ihre Daten ohne jegliche Sicherheit im Klartext speichert.

Unter iOS kann eine Anwendung den Schlüsselbund über die verwenden Keychain Services-API. Die API bietet eine Reihe von Funktionen zum Bearbeiten der im Schlüsselbund der Anwendung gespeicherten Daten. Sehen Sie sich die unter iOS verfügbaren Funktionen an.

  • SecItemAdd Mit dieser Funktion wird ein Element zum Schlüsselbund der Anwendung hinzugefügt.
  • SecItemCopyMatching Mit dieser Funktion können Sie einen Schlüsselbundartikel finden, der der Anwendung gehört.
  • SecItemDelete Wie der Name schon sagt, kann mit dieser Funktion ein Element aus dem Schlüsselbund der Anwendung entfernt werden.
  • SecItemUpdate Verwenden Sie diese Funktion, wenn Sie ein Element im Schlüsselbund der Anwendung aktualisieren möchten.

Das Keychain Services-API ist eine C-API, aber ich hoffe, dass Sie nicht daran gehindert werden. Jede der oben genannten Funktionen akzeptiert ein Wörterbuch (CFDictionaryRef), die ein Elementklassenschlüsselwertpaar und optionale Attributschlüsselwertpaare enthält. Die genaue Bedeutung und der Zweck von jedem wird klar, sobald wir die API in einem Beispiel verwenden.


Verschlüsselung und Entschlüsselung

Wenn Sie über die Verschlüsselung sprechen, hören Sie im Allgemeinen zwei Arten der Verschlüsselung, symmetrisch und asymmetrisch Verschlüsselung. Symmetrische Verschlüsselung verwendet einerseits einen gemeinsamen Schlüssel zum Verschlüsseln und Entschlüsseln von Daten. Die asymmetrische Verschlüsselung hingegen verwendet einen Schlüssel zum Verschlüsseln von Daten und einen anderen separaten, jedoch verwandten Schlüssel zum Entschlüsseln von Daten.

In diesem Tutorial nutzen wir die Sicherheitsrahmen Auf iOS verfügbar, um Daten zu verschlüsseln und zu entschlüsseln. Dieser Prozess findet unter der Haube statt, sodass wir nicht direkt mit diesem Framework interagieren. In unserer Beispielanwendung verwenden wir symmetrische Verschlüsselung.

Das Sicherheitsrahmen bietet eine Reihe weiterer Dienste an, z. B. Randomization-Dienste zum Generieren kryptographisch sicherer Zufallszahlen, Zertifikat, Schlüssel und Vertrauensdienste zum Verwalten von Zertifikaten, öffentlichen und privaten Schlüsseln sowie Vertrauensrichtlinien. Das Sicherheitsrahmen ist ein einfaches Framework, das sowohl für iOS als auch für OS X mit C-basierten APIs verfügbar ist.


Anwendungsübersicht

In diesem Lernprogramm werde ich Ihnen zeigen, wie Sie die Keychain Services-API und die symmetrische Verschlüsselung in einer iOS-Anwendung verwenden können. Wir erstellen eine kleine Anwendung, die vom Benutzer aufgenommene Fotos sicher speichert.

In diesem Projekt verwenden wir Sam Soffes SSKeychain, einen Objective-C-Wrapper für die Interaktion mit der Keychain Services-API. Zur Ver- und Entschlüsselung verwenden wir RNCryptor, eine Verschlüsselungsbibliothek eines Drittanbieters.


Daten verschlüsseln mit RNCryptor

Die RNCryptor-Bibliothek ist eine gute Wahl zum Verschlüsseln und Entschlüsseln von Daten. Das Projekt wird von vielen Entwicklern verwendet und von seinen Erstellern aktiv gepflegt. Die Bibliothek bietet eine einfach zu verwendende Objective-C-API. Wenn Sie mit Cocoa und Objective-C vertraut sind, ist die Verwendung einfach. Die Hauptfunktionen der Bibliothek sind unten aufgeführt.

  • AES-256-Verschlüsselung
  • CBC-Modus
  • Passwort-Stretching mit PBKDF2
  • Passwort salzen
  • Zufällige IV
  • Encrypt-Then-Hash-HMAC

Anwendungsablauf

Bevor wir mit dem Erstellen der Anwendung beginnen, möchte ich Ihnen zeigen, wie der typische Ablauf der Anwendung aussehen wird.

  • Wenn der Benutzer die Anwendung startet, wird ihm eine Ansicht zum Anmelden angezeigt.
  • Wenn sie noch kein Konto erstellt hat, werden ihre Zugangsdaten zum Schlüsselbund hinzugefügt und sie ist angemeldet.
  • Wenn sie ein Konto hat und ein falsches Kennwort eingibt, wird eine Fehlermeldung angezeigt.
  • Nach der Anmeldung hat sie Zugriff auf die Fotos, die sie mit der Anwendung aufgenommen hat. Die Fotos werden von der Anwendung sicher gespeichert.
  • Immer wenn sie ein Foto mit der Kamera des Geräts macht oder ein Foto aus ihrer Fotobibliothek auswählt, wird das Foto verschlüsselt und in der Anwendung gespeichert Unterlagen Verzeichnis.
  • Wenn sie zu einer anderen Anwendung wechselt oder das Gerät gesperrt wird, wird sie automatisch abgemeldet.

Anwendung erstellen

Schritt 1: Projekt einrichten

Starten Sie Xcode und erstellen Sie ein neues Projekt, indem Sie die Option auswählen Einzelansicht-Anwendung Vorlage aus der Liste der Vorlagen.


Nennen Sie das Projekt Sichere Fotos und setzen Gerätefamilie auf das iPhone. Teilen Sie Xcode mit, wo Sie das Projekt speichern möchten, und klicken Sie auf Erstellen.


Schritt 2: Frameworks

Der nächste Schritt ist die Verknüpfung des Projekts mit der Sicherheit und Mobile Core Services Rahmenbedingungen. Wählen Sie das Projekt in der Projektnavigator Wählen Sie links das erste benannte Ziel aus Sichere Fotos, und öffnen Sie die Baue Phasen Tab oben. Erweitere die Binäres mit Bibliotheken verknüpfen Schublade und verknüpfen das Projekt gegen die Sicherheit und Mobile Core Services Rahmenbedingungen.


Schritt 3: Abhängigkeiten

Wie bereits erwähnt, werden wir die SSKeychain-Bibliothek und die RNCryptor-Bibliothek verwenden. Laden Sie diese Abhängigkeiten herunter und fügen Sie sie dem Projekt hinzu. Kopieren Sie die Dateien in Ihr Projekt und fügen Sie sie dem hinzu Sichere Fotos Ziel wie in der Abbildung unten gezeigt.


Schritt 4: Klassen erstellen

Wir zeigen die Fotos des Benutzers in einer Sammlungsansicht an, das heißt, wir müssen eine Unterklasse erstellen UICollectionViewController ebenso gut wie UICollectionViewCell. Wählen Neu> Datei… von dem Datei Erstellen Sie eine Unterklasse von UICollectionViewController, und nennen Sie es MTPhotosViewController. Wiederholen Sie diesen Schritt noch einmal für MTPhotoCollectionViewCell, das ist eine Unterklasse von UICollectionViewCell.

Schritt 5: Erstellen der Benutzeroberfläche

Öffnen Sie das Haupt-Storyboard des Projekts und aktualisieren Sie das Storyboard wie in der Abbildung unten gezeigt. Das Storyboard enthält zwei Ansichtscontroller, eine Instanz von MTViewController, enthält zwei Textfelder und eine Schaltfläche sowie eine Instanz von MTPhotosViewController. Das MTViewController Instanz ist in einen Navigationscontroller eingebettet.

Wir müssen auch ein Segment von der erstellen MTViewController Instanz zum MTPhotosViewController Beispiel. Legen Sie die ID des Segues auf fest photosViewController. Das MTPhotosViewController Die Instanz sollte auch einen Bar-Button enthalten, wie in der Abbildung unten gezeigt.


Damit dies funktioniert, müssen wir die Benutzeroberfläche von aktualisieren MTViewController Wie nachfolgend dargestellt. Wir deklarieren für jedes Textfeld einen Ausgang und eine Aktion, die durch die Schaltfläche ausgelöst wird. Stellen Sie die erforderlichen Verbindungen im Haupt-Storyboard des Projekts her.

 #einführen  @interface MTViewController: UIViewController @property (schwach, nicht atomar) IBOutlet UITextField * usernameTextField; @ property (schwach, nicht atomar) IBOutlet UITextField * passwordTextField; - (IBAction) Login: (ID) Absender; @Ende

In dem MTPhotosViewController Klasse, deklarieren Sie eine Eigenschaft namens Nutzername zum Speichern des Benutzernamens des aktuell angemeldeten Benutzers und zum Deklarieren einer Aktion für das Element der Bar-Schaltfläche. Vergessen Sie nicht, die Aktion mit dem Bar-Button-Element im Haupt-Storyboard zu verbinden.

 #einführen  @Interface MTPhotosViewController: UICollectionViewController @property (Kopie, nicht atomar) NSString * Benutzername; - (IBAction) -Fotos: (ID) -Sender; @Ende

Schritt 6: Implementieren MTViewController

Im MTViewController.m, Fügen Sie eine Importanweisung für die hinzu MTPhotosViewController Klasse, die SSKeychain Klasse und die MTAppDelegate Klasse. Wir passen auch die an MTViewController Klasse zum UIAlertViewDelegate Protokoll.

 #import "MTViewController.h" #import "SSKeychain.h" #import "MTAppDelegate.h" #import "MTPhotosViewController.h" @interface MTViewController ()  @Ende

Der nächste Schritt ist die Implementierung der Anmeldung: Aktion, die wir früher erklärt haben Wir prüfen zunächst, ob der Benutzer bereits ein Konto erstellt hat, indem Sie das Kennwort für das Konto abrufen. Ist dies der Fall, verwenden wir den Schlüsselbund der Anwendung, um festzustellen, ob das vom Benutzer eingegebene Kennwort mit dem im Schlüsselbund gespeicherten Kennwort übereinstimmt. Die von der SSKeychain Die Bibliothek erleichtert das Lesen und Bearbeiten von Daten, die im Schlüsselbund der Anwendung gespeichert sind.

 - (IBAction) login: (id) sender if (self.usernameTextField.text.length> 0 && self.passwordTextField.text.length> 0) NSString * password = [SSKeychain passwordForService: @ "MyPhotos" -Konto: self.usernameTextField .Text]; if (password.length> 0) if ([self.passwordTextField.text isEqualToString: password]) [self performSegueWithIdentifier: @ "photosViewController" sender: nil];  else UIAlertView * alertView = [[UIAlertView-Zuordnung] initWithTitle: @ Meldung "Fehleranmeldung": @ "Ungültige Kombination aus Benutzername und Kennwort." Delegat: nil cancelButtonTitle: @ "OK" otherButtonTitles: nil]; [alertView show];  else UIAlertView * alertView = [[UIAlertView-Zuordnung] initWithTitle: @ Meldung "Neues Konto": @ "Möchten Sie ein Konto erstellen?" Delegat: self cancelButtonTitle: @ "Cancel" otherButtonTitles: @ "OK", nil]; [alertView show];  else UIAlertView * alertView = [[UIAlertView-Zuordnung] initWithTitle: @ Meldung "Error Input": @ "Benutzername und / oder Kennwort dürfen nicht leer sein." Delegat: nil cancelButtonTitle: @ "OK" otherButtonTitles: nil]; [alertView show]; 

Wir haben den Ansichtscontroller als Delegierten der Warnungsansicht festgelegt, was bedeutet, dass wir den implementieren müssen UIAlertViewDelegate Protokoll. Schauen Sie sich die Implementierung von an alertView: clickedButtonAtIndex: unten gezeigt.

 -(void) alertView: (UIAlertView *) alertView clickedButtonAtIndex: (NSInteger) buttonIndex switch (buttonIndex) case 0: break; Fall 1: [self createAccount]; brechen; Standard: Pause; 

Im Benutzerkonto anlegen, wir nutzen die SSKeychain Klasse, um den vom Benutzer gewählten Benutzernamen und das Kennwort sicher zu speichern. Wir rufen dann an performSegueWithIdentifier: Absender:.

 - (void) createAccount BOOL result = [SSKeychain setPassword: self.passwordTextField.text forService: @ "MyPhotos" -Konto: self.usernameTextField.text]; if (Ergebnis) [self performSegueWithIdentifier: @ "photosViewController" sender: nil]; 

Im prepareForSegue: Absender:, Wir bekommen einen Hinweis auf die MTPhotosViewController Beispiel, setzen Sie seine Nutzername Eigenschaft mit dem Wert von BenutzernameTextField, und setzen Sie das zurück passwordTextField.

 - (void) prepareForSegue: (UIStoryboardSegue *) Absender Absender: (ID) Absender MTPhotosViewController * photosViewController = segue.destinationViewController; photosViewController.username = self.usernameTextField.text; self.passwordTextField.text = nil; 

Schritt 7: Implementieren MTPhotosCollectionViewCell

Öffnen MTPhotosCollectionViewCell.h und deklarieren Sie eine Filiale mit dem Namen Bildansicht vom Typ UIImageView.

 #einführen  @Interface MTPhotoCollectionViewCell: UICollectionViewCell @property (schwach, nicht atomar) IBOutlet UIImageView * imageView; @Ende

Öffne das Haupt-Storyboard und füge eine hinzu UIImageView Beispiel zur Prototypzelle der MTPhotosViewController Beispiel. Wählen Sie die Prototypzelle (nicht die Bildansicht) aus und setzen Sie ihre Klasse auf MTPhotosCollectionViewCell in dem Identitätsinspektor zur Rechten. Öffnen Sie bei noch markierter Prototypzelle die Attribute-Inspektor und setzen Sie den Bezeichner auf Fotozelle.

Schritt 8: Implementieren MTPhotosViewController

Importieren Sie zunächst die erforderlichen Header-Dateien in MTPhotosViewController.m Wie nachfolgend dargestellt. Wir müssen auch zwei Eigenschaften angeben, Fotos Zum Speichern des Arrays von Fotos werden in der Sammlungsansicht und angezeigt Dateipfad um einen Verweis auf den Dateipfad zu behalten. Sie haben vielleicht bemerkt, dass die MTPhotosViewController Klasse entspricht der UIActionSheetDelegate, UINavigationControllerDelegate, und UIImagePickerControllerDelegate Protokolle.

 #import "MTPhotosViewController.h" #import  #import "RNDecryptor.h" #import "RNEncryptor.h" #import "MTPhotoCollectionViewCell.h" @interface MTPhotosViewController ()  @ Eigenschaft (stark, nichtatomisch) NSMutableArray * -Fotos; @ property (copy, nonatomic) NSString * filePath; @Ende

Ich habe auch eine Komfort- oder Hilfsmethode implementiert, setupUserDirectory, zum Erstellen und Einrichten der erforderlichen Verzeichnisse, in denen die Benutzerdaten gespeichert werden. Im bereiten Sie Daten vor, Die Anwendung entschlüsselt die Bilder, die im sicheren Verzeichnis des Benutzers gespeichert sind. Sehen Sie sich die Implementierungen unten an.

 - (void) setupUserDirectory NSArray * pfade = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * documents = [pfade objectAtIndex: 0]; self.filePath = [Dokumente stringByAppendingPathComponent: self.username]; NSFileManager * fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath: self.filePath]) NSLog (@ "Verzeichnis bereits vorhanden.");  else NSError * error = nil; [fileManager createDirectoryAtPath: self.filePath withIntermediateDirectories: YES-Attribute: keine Fehler: & Fehler]; if (error) NSLog (@ "Verzeichnis für Benutzer kann nicht erstellt werden."); 
 - (void) prepareData self.photos = [[NSMutableArray Allocation] init]; NSFileManager * fileManager = [NSFileManager defaultManager]; NSError * error = nil; NSArray * contents = [fileManager contentsOfDirectoryAtPath: Self.filePath-Fehler: & Fehler]; if ([Inhaltszähler] &&! -Fehler) NSLog (@ "Inhalt des Benutzerverzeichnisses.% @", Inhalt); for (NSString * fileName im Inhalt) if ([fileName rangeOfString: @ ". protectedData"]. length> 0) NSData * data = [NSData dataWithContentsOfFile: [self.filePath stringByAppendingPathComponent: fileName]]; NSData * decryptedData = [RNDecryptor decryptData: data withSettings: kRNCryptorAES256Einstellungspasswort: @ "A_SECRET_PASSWORD" Fehler: nil]; UIImage * image = [UIImage imageWithData: decryptedData]; [self.photos addObject: Bild];  else NSLog (@ "Diese Datei ist nicht gesichert.");  else if (! [Inhaltsanzahl]) if (Fehler) NSLog (@ "Der Inhalt des Benutzerverzeichnisses kann nicht gelesen werden.");  else NSLog (@ "Das Verzeichnis des Benutzers ist leer."); 

Rufen Sie beide Methoden in den View-Controllern auf viewDidLoad Methode wie unten gezeigt.

 - (void) viewDidLoad [super viewDidLoad]; [self setupUserDirectory]; [Selbstvorbereitungsdaten]; 

Die Bar-Schaltfläche in der Navigationsleiste des View-Controllers zeigt ein Aktionsblatt, in dem der Benutzer zwischen der Kamera des Geräts und der Fotobibliothek wählen kann.

 - (IBAction) photos: (id) sender UIActionSheet * actionSheet = [[UIActionSheet-Zuordnung] initWithTitle: @ "Quelle auswählen" delegieren: self cancelButtonTitle: @ "Abbrechen" destructiveButtonTitle: nil otherButtonTitles: @ "Camera", @ "Photo Library" null]; [actionSheet showFromBarButtonItem: Sender animiert: JA]; 

Lass uns implementieren actionSheet: clickedButtonAtIndex: des UIActionSheetDelegate Protokoll.

 - (void) actionSheet: (UIActionSheet *) actionSheet clickedButtonAtIndex: (NSInteger) buttonIndex if (buttonIndex.) < 2)  UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.mediaTypes = @[(__bridge NSString *)kUTTypeImage]; imagePickerController.allowsEditing = YES; imagePickerController.delegate = self; if (buttonIndex == 0)  #if TARGET_IPHONE_SIMULATOR #else imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; #endif  else if ( buttonIndex == 1)  imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  [self.navigationController presentViewController:imagePickerController animated:YES completion:nil];  

Um die Auswahl des Benutzers in der Image Picker-Steuerung zu handhaben, müssen wir implementieren imagePickerController: didFinishPickingMediaWithInfo: des UIImagePickerControllerDelegate Protokoll wie unten gezeigt. Das Bild wird mit verschlüsselt encryptData des RNEncryptor Bibliothek. Das Bild wird auch dem hinzugefügt Fotos Array und die Sammlungsansicht wird neu geladen.

 - (void) imagePickerController: (UIImagePickerController *) - Auswahlfeld didFinishPickingMediaWithInfo: (NSDictionary *) info UIImage * image = [info objectForKey: UIImagePickerControllerEditedImage]; if (! image) [info objectForKey: UIImagePickerControllerOriginalImage];  NSData * imageData = UIImagePNGRepresentation (image); NSString * imageName = [NSString stringWithFormat: @ "image-% d.securedData", self.photos.count + 1]; NSData * encryptedImage = [RNEncryptor encryptData: imageData withSettings: kRNCryptorAES256Settings-Kennwort: @ "A_SECRET_PASSWORD" Fehler: nil]; [encryptedImage writeToFile: [self.filePath stringByAppendingPathComponent: imageName] atomisch: YES]; [self.photos addObject: Bild]; [self.collectionView reloadData]; [picker dismissViewControllerAnimated: YES completion: nil]; 

Bevor Sie die Anwendung erstellen und ausführen können, müssen Sie das implementieren UICollectionViewDataSource Protokoll wie unten gezeigt.

 - (NSInteger) collectionView: (UICollectionView *) collectionView numberOfItemsInSection: (NSInteger) Abschnitt return self.photos? self.photos.count: 0; 
 - (UICollectionViewCell *) collectionView: (UICollectionView *) collectionView cellForItemAtIndexPath: (NSIndexPath *) indexPath MTPhotoCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier: @ "PhotoCell" fürIndexPath: cell.imageView.image = [self.photos objectAtIndex: indexPath.row]; zurück Zelle; 

Schritt 9: Behandeln von Anwendungszuständen

Wenn die Anwendung in den Hintergrund wechselt, muss der Benutzer abgemeldet werden. Dies ist aus Sicherheitsgründen wichtig. Um dies zu erreichen, muss der Anwendungsdelegierte über einen Verweis auf den Navigationscontroller verfügen, damit er in den Root-View-Controller des Navigationsstapels gelangen kann. Beginnen Sie mit der Deklaration einer Eigenschaft namens navigationController im MTAppDelegate.h.

 #einführen  @Interface MTAppDelegate: UIResponder  @ property (strong, nonatomic) UIWindow * -Fenster; @ property (strong, nonatomic) UINavigationController * navigationController; @Ende

In der Ansicht Controller viewDidLoad Als Methode legen wir die Anwendungsdelegaten fest navigationController Eigenschaft wie unten gezeigt. Denken Sie daran, dass dies nur eine Möglichkeit ist, damit umzugehen.

Ich habe die obige Eigenschaft in eingestellt ViewController's viewDidLoad Methode wie unten gezeigt.

 - (void) viewDidLoad [super viewDidLoad]; MTAppDelegate * applicationDeleagte = (MTAppDelegate *) [[UIApplication sharedApplication] -Delegat]; [applicationDeleagte setNavigationController: self.navigationController]; 

Im Anwendungsdelegierten müssen wir aktualisieren applicationWillResignActive: Wie nachfolgend dargestellt. So einfach ist das. Das Ergebnis ist, dass der Benutzer abgemeldet wird, wenn die Anwendung den Fokus verliert. Dadurch werden die in der Anwendung gespeicherten Bilder des Benutzers vor neugierigen Blicken geschützt. Der Nachteil ist, dass sich der Benutzer anmelden muss, wenn die Anwendung wieder aktiv wird.

 - (void) applicationWillResignActive: (UIApplication *) Anwendung [self.navigationController popToRootViewControllerAnimated: NO]; 

Schritt 10: Erstellen und ausführen

Erstellen Sie das Projekt und führen Sie die Anwendung aus, um es auf Herz und Nieren zu testen.


Fazit

In diesem Lernprogramm haben Sie gelernt, wie Sie die Keychain Services-API zum Speichern vertraulicher Daten verwenden. Außerdem haben Sie erfahren, wie Sie Bilddaten unter iOS verschlüsseln. Hinterlassen Sie einen Kommentar in den Kommentaren, wenn Sie Fragen oder Anregungen haben.