Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 Hello iPhone
2 Die Reise nach iOS
3 Sehen und anfassen
4 Alles unter Kontrolle
5 Daten, Tabellen und Controller
6 Models, Layer, Animationen
7 Programmieren, aber sicher
8 Datenserialisierung und Internetzugriff
9 Multimedia
10 Jahrmarkt der Nützlichkeiten
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
Apps programmieren für iPhone und iPad von Klaus M. Rodewig, Clemens Wagner
Das umfassende Handbuch
Buch: Apps programmieren für iPhone und iPad

Apps programmieren für iPhone und iPad
Rheinwerk Computing
1172 S., geb., mit DVD
49,90 Euro, ISBN 978-3-8362-2734-6
Pfeil 7 Programmieren, aber sicher
Pfeil 7.1 iOS und Hardware
Pfeil 7.2 Bedrohungen, Angriffe, Sicherheitslücken und Maßnahmen
Pfeil 7.2.1 Arten von Sicherheitslücken
Pfeil 7.3 Threat Modeling
Pfeil 7.3.1 Erstellen eines Datenflussdiagramms
Pfeil 7.3.2 STRIDE
Pfeil 7.3.3 Generische Designgrundsätze
Pfeil 7.3.4 Threat Modeling aus der Tube – das Microsoft SDL Threat Modeling Tool
Pfeil 7.4 Sichere Programmierung in der Praxis
Pfeil 7.4.1 Authentisierung
Pfeil 7.4.2 Keychain
Pfeil 7.4.3 Jailbreak-Erkennung
Pfeil 7.4.4 Verzeichnisse und Dateiattribute
Pfeil 7.4.5 Event-Handling
Pfeil 7.4.6 Screenshots
Pfeil 7.4.7 Sorgfältiger Umgang mit der Bildschirmsperre
Pfeil 7.4.8 Struktur und Ordnung im Sandkasten
Pfeil 7.4.9 UDID ist tot. Was nun?
Pfeil 7.4.10 Base64
Pfeil 7.5 iCloud
Pfeil 7.5.1 Denkanstöße
Pfeil 7.5.2 iCloud in der Praxis
Pfeil 7.5.3 Key-Value-Storage
Pfeil 7.5.4 Verschlüsselung (in der Cloud)

Rheinwerk Computing - Zum Seitenanfang

7.5iCloudZur nächsten Überschrift

iCloud ist die Apple-Variante des Cloud-Computings, das seit einigen Jahren in nahezu jedem Gespräch unter IT-Fachleuten erwähnt wird. Cloud-Computing oder einfach nur die Cloud, wie die coolen Leute sagen, ist der große Hype unserer Zeit. Wer schon länger im IT-Geschäft ist, wird bereits so manchen Hype erlebt haben. Die »Demokratisierung« der IT durch Windows in den 1990er Jahren war noch relativ harmlos. Schlimm wurde es zur Jahrtausendwende. Wer am neuen Markt sein Geld in heute nicht mehr existierende Internetfirmen investiert hatte, der wird wissen, was ein IT-Hype ist. Leider hat der Neue Markt viele Nicht-ITler auf IT aufmerksam gemacht, so dass seitdem jede auch noch so unscheinbare Neuerung in der IT mit großem Hallo hochgejubelt wird, als sei es die Erfindung der Weltformel.

Wer erinnert sich nicht an die Zeit, in der XML bekannt wurde? Jeder, der das Wort »Computer« fehlerfrei buchstabieren konnte und mit Anzug und Krawatte bewaffnet war, sah in XML die Lösung aller Probleme der Menschheit. »Leute, es ist nur eine Auszeichnungssprache!«, wollte man diesen armen Menschen zurufen. Vergebens.

Dann kam das Web 2.0 über uns. Eine nette Idee, die aber von den einschlägigen Protagonisten ebenfalls so umfassend in Beschlag genommen wurde, dass sich jedem ITler beim Hören des Begriffs »Web 2.0« die Nackenhaare hochstellen.

Abbildung

Abbildung 7.42 Der Web-Teil der iCloud

Und genauso ist es mit der Cloud. Cloud-Computing ist heute in den allermeisten Fällen im professionellen IT-Umfeld nicht mehr als ein falsch verstandenes Synonym für Outsourcing. Man mietet als Firma Kapazitäten in Form von Rechenzentren, Diensten oder Anwendungen und lagert dorthin eigene IT-Funktionalität aus. Eigentlich kommt die Idee des Cloud-Computings aus den Anforderungen großer Internetfirmen wie Amazon oder Google. Diese Firmen haben prinzipbedingt mit großen Lastspitzen zu kämpfen, je nachdem, welches Ereignis die Benutzer dazu bringt, auf die Web-Präsenzen zuzugreifen.

Außer bei globalen Ereignissen, wie z. B. den Terroranschlägen vom 11. September 2001, bei denen so gut wie alle Nachrichtenseiten rund um dem Globus unter der Last der Anfragen zusammenbrachen, haben globale Anbieter wie Amazon oder Google in der Regel mit lokal begrenzten Lastspitzen zu kämpfen. Um solche Lastspitzen ohne Ausfälle oder Einschränkungen in der Erreichbarkeit und Funktionalität meistern zu können, wurde die Idee des Cloud-Computings geboren. Dahinter verbirgt sich zunächst nicht mehr als das dynamische, bedarfsgerechte Verwalten und Verteilen von IT-Ressourcen über ein Netzwerk – in der Regel das Internet. Es gibt einen großen Pool verteilter Ressourcen, und je nachdem, wo gerade aufgrund einer Lastspitze Ressourcen benötigt werden, weist man dort entsprechende Ressourcen aus dem Pool zu.

Clouds gibt es in verschiedenen Geschmacksrichtungen. Sie werden im Zusammenhang mit Cloud vielleicht über die Begriffe IaaS (Infrastructure as a Service), SaaS (Software as a Service) und PaaS (Platform as a Service) gestolpert sein. Dahinter verbirgt sich, dass Sie Cloud-Ressourcen als nackte Infrastruktur haben (IaaS) haben können, als Plattform für eigene Anwendungen (PaaS) oder als fertige Anwendungen in der Cloud (SaaS). Das ist für Leute, die IT-Outsourcing kennen, nichts Neues. Neu daran sind nur die mittlerweile große Verbreitung und die dynamische Verwaltung von Ressourcen.

Wenn Sie Google Docs oder Microsoft Office 365 kennen, dann kennen Sie bereits Clouds aus dem Bereich SaaS. Die bekannteste Cloud aus dem Bereich IaaS ist wohl die Elastic Compute Cloud von Amazon, Amazon EC2. PaaS-Vertreter sind die Google App Engine und Microsoft Azure. Als Apple-Benutzer haben Sie vielleicht mit Mobile Me gearbeitet. Die Onlineversionen der Mail- und Kalender-App sind typische Vertreter von SaaS; die iDisk und die Anbindung von iPhoto und iWeb fallen eher in den Bereich PaaS.

Ein weiterer, sich rasch verbreitender Anwendungsfall für Cloud-Computing ist der Speicher im Netz. Diese Idee, die die beiden Wolfgangs vom legendären Computerclub bereits Anfang der 1990er Jahre hatten, hat sich für Apple-Benutzer in Form der iCloud manifestiert. Diese ist zwar, vom Browser aus bedient, eine SaaS, denn auch in der iCloud gibt es die Online-Pendants zur Mail-, Kalender-, Kontakte- und iPhone-Suchen-App. Für App-Entwickler ist aber insbesondere der PaaS-Teil interessant, der einen Synchronisations- und Speicherdienst anbietet, über den Apps und Mac-Programme Daten in der iCloud ablegen und über mehrere Geräte synchronisieren können.

Sie können Dokumente aus einer App direkt in der iCloud ablegen und die iCloud auf diese Weise als Speicherplatz verwenden. In den Dokumenten können Sie Suchoperationen ausführen und die Dokumente über mehrere Endgeräte synchronisieren.

Darüber hinaus beherrscht die iCloud Key-Value-Storing. Sie können kleine Datenpakete direkt aus Objekten heraus in die Cloud legen. Die Idee dahinter ist einleuchtend: Stellen Sie sich beispielsweise ein Spiel vor, das den aktuellen Spielstand über Key-Value-Storing in die Cloud legt, so dass Sie das Spiel auf iPad, iPhone und Mac spielen können und immer an der letzten Stelle weitermachen, egal, an welchem Gerät Sie gerade sind.


Rheinwerk Computing - Zum Seitenanfang

7.5.1DenkanstößeZur nächsten ÜberschriftZur vorigen Überschrift

Bevor es ans Programmieren geht, müssen wir an dieser Stelle noch kurz den ermahnenden Zeigefinger heben. Das Killer-Argument für die Cloud ist stets Verfügbarkeit. Durch die Verteilung auf unglaublich viele Rechner, Netzwerke, Komponenten und Rechenzentren ist der Ausfall einer Cloud so gut wie ausgeschlossen. Bedauerliche Einzelfälle gibt es natürlich immer wieder. Auch die großen Anbieter hatten bereits einen oder mehrere Ausfälle ihrer Cloud-Infrastruktur zu verzeichnen – zum Teil mit tagelangen Einschränkungen der Erreichbarkeit, zum Teil auch mit größeren Datenverlusten:

  • Amazon: Ausfall von mehreren Tagen und Datenverlust durch Fehler in einem Rechenzentrum
  • Google: Versehentliche Löschung der Inhalte von über 150.000 Postfächern des Dienstes Googlemail durch einen Softwarefehler
  • Microsoft: Ein Hausmeister-Skript, das verdächtige Konten löschen sollte, war übereifrig und löschte über 17.000 »normale« Konten mit.
  • Microsoft und Amazon: teilweiser Ausfall der Cloud-Dienste durch Blitzschlag in Irland
  • Persönliche Erfahrung eines der beiden Autoren: versehentliches Löschen des iTunes-Match-Dienstes inklusive der gesamten darin abgelegten Musikbibliothek durch einen Apple-Mitarbeiter

Ausfallsicherheit und die sichere Ablage von Daten in der Cloud sind daher in der Theorie nette Ideen, aber wie bei allen Ideen, an deren Umsetzung Menschen beteiligt sind, sieht die Praxis weniger rosig aus. Dies sollten Sie stets im Hinterkopf behalten, wenn Sie Ihre App an die iCloud anbinden. Es gibt unendlich viele Anwendungsfälle, in denen die Verwendung von Cloud-Diensten sinnvoll sein kann, genauso gibt es unendlich viele Anwendungsfälle, in denen die Verwendung von Cloud-Diensten nicht sinnvoll ist. [Anm.: https://forums.aws.amazon.com/thread.jspa?threadID=65649&tstart=0] Entscheiden Sie weise!

PRISM, Tempora und wie sie alle heißen

2013 sind Details über die Abschnorchelprogramme verschiedener Geheimdienste bekanntgeworden, die Kundendaten direkt an den Servern der großen »Internetfirmen« wie Apple, Google oder Microsoft abzapfen. Dazu zählen natürlich auch und insbesondere alle Daten, die »in der Cloud« liegen, also auch in der iCloud. Was paranoide Zeitgenossen bis dato immer als Schreckensszenario an die Wand gemalt haben, ist leider Realität. Der Grund für diese Datenzugriffe ist nicht nur die Jagd nach Terroristen, sondern gerne auch Wirtschaftsspionage. Ein weiteres Argument, nicht alles ohne die entsprechende Risikoabwägung in die Cloud zu schieben, vor allen Dingen, sich nicht blind auf die Sicherheitsversprechen der Anbieter zu verlassen. Gehen Sie grundsätzlich davon aus, dass Dienste auf alle Daten in der (i)Cloud zugreifen können.

Neben der Verfügbarkeit von Rechenleistung und gespeicherten Daten kommen bei der Verwendung von Cloud-Diensten zwei weitere Aspekte ins Spiel, nämlich Datenschutz und Datensicherheit. Die Natur der Cloud bedingt, dass Sie nie genau wissen, wo sich die Rechner befinden, die sich Ihnen gegenüber als iCloud ausgeben. Die Geräte können in Irland stehen (Europa), aber auch in den USA oder sonst wo, wo Apple gerade Ressourcen für die iCloud verfügbar hat.

Da die iCloud ihrerseits zurzeit auf den Clouds von Amazon und Microsoft läuft [Anm.: http://tinyurl.com/3msst5x] und Apple überdies ein US-amerikanisches Unternehmen ist, müssen Sie beim Speichern personenbezogener Daten in der iCloud Acht geben. Die USA sind zwar dem Safe-Harbor-Abkommen beigetreten, Datenschutz wird in den USA aber trotzdem auf einem wesentlich anderen Niveau betrachtet, als es im Geltungsbereich des Bundesdatenschutzgesetzes der Fall ist. Je nachdem, welche Daten Ihre App verarbeitet, begehen Sie durch die Verwendung der iCloud-Funktionalität daher unter Umständen einen Verstoß gegen das Bundesdatenschutzgesetz. Im Zweifelsfall sollten Sie vorher juristischen Rat einholen.

Laut Apple sind die in der iCloud abgelegten Daten mit »mindestens« AES-128 verschlüsselt. [Anm.: http://support.apple.com/kb/HT4865] Bei korrekter Implementierung und bei der Verwendung eines starken Passworts bietet dieser Algorithmus ausreichende Sicherheit. Offen bleibt aber die Frage, mit welchem Schlüssel die Daten verschlüsselt werden und ob nur der Benutzer oder auch Apple sie entschlüsseln kann. Fraglich ist auch, ob Apple seine eigene Dokumentation befolgt und AES im CBC-Modus ohne Initialisierungsvektor verwendet. [Anm.: http://tinyurl.com/837qxak]

Die iCloud begegnet Ihnen als App-Programmierer an zwei Stellen. Die erste Stelle ist die explizite Verwendung der iCloud in Ihrer eigenen App. Die zweite Stelle ist die iCloud-Backup-Funktion von iOS. Selbst wenn Sie Ihrer App keine iCloud-Anbindung spendieren, wird iOS dennoch alle Dateien Ihrer App in der iCloud sichern, wenn der Benutzer das iCloud-Backup in den Systemeinstellungen aktiviert hat.


Rheinwerk Computing - Zum Seitenanfang

7.5.2iCloud in der PraxisZur nächsten ÜberschriftZur vorigen Überschrift

Für das folgende Beispiel legen Sie ein neues Projekt vom Typ Single View Application an. Das Beispielprojekt finden Sie auf der Buch-CD oder im Git-Repository im Ordner iOS7/iClous.

Damit eine App mit der iCloud arbeiten kann, benötigt sie eine entsprechend konfigurierte App ID. Wie bei der Verwendung der Dataprotection-API in Abschnitt 7.4.4 können Sie dies direkt in Xcode konfigurieren. Öffnen Sie dazu die Projekteinstellungen, und aktivieren Sie im Tab Capabilities den Punkt iCloud. Vor der Aktivierung finden Sie in der Erläuterung die Schritte, die Xcode für Sie erledigt. Das ist zum einen das Aktivieren der iCloud-Fähigkeiten in der App ID und zum anderen das Erzeugen einer Entitlements-Datei. Diese finden Sie anschließend in der Xcode-Navigationsansicht.

Abbildung

Abbildung 7.43 Aktivieren der iCloud-Unterstützung für die App

Nach der Aktivierung der iCloud-Unterstützung müssen Sie im selben Dialog noch die Option Use key-value store aktivieren, damit Sie diese Funktionalität nutzen können (siehe Abbildung 7.44).

Damit eine App die iCloud verwenden kann, muss auf dem betreffenden iDevice ein iCloud-Konto eingerichtet und in den Einstellungen der iCloud der Punkt Dokumente & Daten aktiviert sein (siehe Abbildung 7.46).

Abbildung

Abbildung 7.44 Die App kann jetzt iCloud.

Abbildung

Abbildung 7.45 Die neue Entitlements-Datei

Abbildung

Abbildung 7.46 iCloud-Einstellungen in iOS

Fügen Sie im Kopf des AppDelegate eine Konstante als Identifier für den Cloud-Zugriff über KVC an.

NSString *const CLOUDKEY = @"iClous";

Darüber hinaus benötigt das AppDelegate zwei Propertys:

@property BOOL theCloud;
@property (strong) NSURL *iCloudPath;

Die Property theCloud setzen Sie am Anfang der Methode application didFinishLaunchingWithOptions: auf NO:

self.theCloud = NO;

Da nicht jeder Benutzer die iCloud eingerichtet oder aktiviert hat, ist das Erste, was Sie in einer iCloud-fähigen App machen müssen, auf das Vorhandensein einer funktionierenden iCloud-Verbindung hin zu prüfen. Fügen Sie dazu im AppDelegate am Ende der Methode application didFinishLaunchingWithOptions: den folgenden Code ein:

01 dispatch_async(dispatch_get_global_queue  
(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
02 NSURL *iCloud = [[NSFileManager
defaultManager] URLForUbiquityContainerIdentifier:nil];
03 if (iCloud) {
04 dispatch_async(dispatch_get_main_queue(), ^{
05 NSLog(@"iCloud-Verzeichnis: %@", iCloud);
06 [self setTheCloud:YES];
07 });
08 }
09 else {
10 dispatch_async(dispatch_get_main_queue(), ^{
11 NSLog(@"No iCloud");
12 [self setTheCloud:NO];
13 });
14 }
15 });

Listing 7.28 Prüfen auf iCloud-Fähigkeit

Die eigentliche Kommunikation mit der iCloud erfolgt über die NSFilemanager-Methode URLForUbiquityContainerIdentifier in Zeile 2. Diese Methode ist mit iOS 5 neu zu NSFileManager hinzugekommen und liefert den iCloud-Container zurück, in dem die App ihre Daten speichern kann. Liefert der Aufruf dieser Methode nil zurück, funktioniert die Verbindung mit der iCloud nicht. Der Aufruf ist also ein verlässlicher Indikator dafür, ob eine App mit der iCloud arbeiten kann oder nicht.

Da die Methode, wie alle Netzwerkverbindungen, einige Zeit benötigen kann, bis sie zurückkehrt, sollten Sie sie nicht aus dem Hauptthread der App aus aufrufen, denn solange die Methode auf eine Antwort von der iCloud wartet, ist der Thread blockiert. Im Falle des Hauptthreads wäre das also die gesamte App. Daher ist der Aufruf in einen Block gekapselt (siehe Kapitel 2, »Die Reise nach iOS«), der die Methode in eine Dispatch Queue von Grand Central Dispatch legt, sie dort ausführt und anschließend zum Hauptthread der App zurückkehrt.

Grand Central Dispatch

Grand Central Dispatch (GCD) ist eine von Apple entwickelte Bibliothek zum einfachen Verteilen von Programmoperationen auf mehrere Prozessoren bzw. Prozessorkerne. Nebenläufige Programmierung, also das Erzeugen von mehreren Ausführungssträngen, ist seit jeher ein kompliziertes und fehlerträchtiges Thema. Mit der flächendeckenden Verbreitung von Mehrkern-Prozessoren ist die nebenläufige Programmierung aber eine Grundanforderungen in der Softwareentwicklung geworden.

Apple hat mit GCD eine Bibliothek geschaffen, mit der ein Programmierer unabhängig von der tatsächlichen Arbeit nebenläufig programmieren kann. Er muss die Aufgaben, die auf verschiedene Ausführungsstränge aufgeteilt werden sollen, nur an GCD übergeben, und GCD kümmert sich um die weitere Verteilung. Der Programmierer übergibt Tasks, wie in Listing 7.28 gezeigt, und muss sich nicht um Begriffe und Techniken wie Threads und Prozesse kümmern; das erledigt GCD.

Wenn Sie die App übersetzen und auf einem iDevice mit aktiviertem iCloud-Konto ausführen, werden Sie die folgende Ausgabe erhalten:

iClous[6271:60b] iCloud-Verzeichnis:  
file:///private/var/mobile/Library/Mobile%20Documents/
R42P59E5WA~de~cocoaneheads~iClous/

Das Verzeichnis, das außerhalb der Sandbox der App liegt, ist das zentrale iCloud-Verzeichnis für diese App, der Ubiquity-Container. Der iCloud-Dienst von iOS überträgt Dateien aus diesem Verzeichnis in die iCloud und überträgt umgekehrt Dateien aus der iCloud zurück in dieses Verzeichnis; es ist also eine lokale Kopie der Daten in der iCloud. Als App-Programmierer kommunizieren Sie also lediglich indirekt über Dateioperationen mit der iCloud, nicht direkt über Netzwerkverbindungen.

Der Ubiquity-Container ist das einzige Verzeichnis außerhalb der Sandbox, in das eine App schreiben darf (neben dem tmp-Verzeichnis). Über die Vergabe von Entitlements geben Sie einer App die Erlaubnis, in den betreffenden Ubiquity-Container zu schreiben. Sie können einen Ubiquity-Container auch von verschiedenen Apps nutzen lassen. Dabei ist dann Vorsicht geboten, um den ungewollten Zugriff einer App auf die Daten einer anderen App im selben Ubiquity-Container zu vermeiden. Für den Normalfall sind Sie gut damit beraten, jeder App ihren eigenen Ubiquity-Container zuzuweisen.

Die eindeutige Festlegung des Ubiquity-Containers für eine App dient noch einem anderen Zweck als der Trennung von verschiedenen Apps. Dadurch, dass eine App auf allen Geräten denselben Ubiquity-Container verwendet, ist der Datenaustausch per iCloud ganz profan.


Rheinwerk Computing - Zum Seitenanfang

7.5.3Key-Value-StorageZur nächsten ÜberschriftZur vorigen Überschrift

Die wohl praktischste Funktion der iCloud ist der Key-Value-Storage. Dahinter verbirgt sich nichts anderes als die von NSUserDefaults bekannte Technik, Daten über Schlüssel zu speichern. Der Unterschied ist, dass diese Daten beim Speichern in der iCloud umgehend allen Geräten zur Verfügung stehen, auf denen die betreffende App installiert ist. Sie können als Programmierer auf diese Weise also ganz bequem Daten innerhalb einer App über verschiedene Endgeräte synchronisieren, ohne dass Sie sich Gedanken über ein Protokoll und seine Synchronisierung machen müssen.

Erweitern Sie den im vorherigen Abschnitt implementierten GDC-Aufruf zur Prüfung auf iCloud-Fähigkeit um die folgenden Zeilen:

NSString *theLocalText = @"Lorem ipsum dolor sit 
amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt ut labore et dolore magna
aliquyam erat, sed diam voluptua.";
// Key Value Store
NSUbiquitousKeyValueStore *cloudStore =
[NSUbiquitousKeyValueStore defaultStore];
if([[cloudStore stringForKey:CLOUDKEY] length] == 0){
NSLog(@"Kein Text in der Cloud gefunden");
[cloudStore setString:theLocalText forKey:CLOUDKEY];
[cloudStore synchronize];
} else {
NSLog(@"Die Cloud sagt: %@", [cloudStore
stringForKey:CLOUDKEY]);
}

Listing 7.29 Key-Value-Storage in der iCloud

Der Bezeichner CLOUDKEY ist das konstante NSString-Objekt, das Sie oben im AppDelegate definiert haben.

Wie bei der Verwendung von NSUserDefaults legen Sie über den Aufruf der Klasse NSUbiquitousKeyValueStore ein iCloud-Handle an, mit dem Sie anschließend die gewünschten Operationen ausführen können:

NSUbiquitousKeyValueStore *cloudStore = 
[NSUbiquitousKeyValueStore defaultStore];

Der Zugriff auf Einträge in diesem iCloud-Handle erfolgt über die Verwendung der betreffenden Typ-Accessoren. Für das Auslesen eines Datums vom Typ NSString kommt daher stringForKey zum Einsatz. Der Key ist dabei der eindeutige Schlüssel, der das betreffende Datum identifiziert:

if([[cloudStore stringForKey:CLOUDKEY] length] == 0){

Diese Anweisung prüft, ob in der iCloud für den Schlüssel iClous ein String gespeichert ist. Ist dies der Fall, gibt die App den Text in der else-Anweisung aus, ansonsten setzt sie den Wert über die Methode setString des NSUbiquitousKeyValueStore:

[cloudStore setString:theLocalText forKey:CLOUDKEY];
[cloudStore synchronize];

Listing 7.30 Setzen eines Key-Values in der iCloud

Die Methode synchronize des NSUbiquitousKeyValueStore dient zum expliziten Synchronisieren der lokal gespeicherten Daten mit der iCloud. Der iCloud-Dienst auf dem iDevice synchronisiert neue Daten nicht automatisch nach ihrer Erstellung mit der iCloud, sondern verwendet sein eigenes, von Apple festgelegtes Intervall. Über die Methode synchronize können Sie die Synchronisierung mit der iCloud anstoßen. Apple weist allerdings darauf hin, dass diese Methode sparsam zu verwenden ist, nämlich beim Start einer App und beim Wechseln vom Hintergrund in den Vordergrund. Für den normalen Betrieb ist dies sicher ausreichend, aber gerade beim Testen ist das Warten auf die automatische Synchronisierung sehr umständlich. Sie sollten den Gebrauch von synchronize vor dem Deployment Ihrer App in den App Store also auf die von Apple empfohlenen Anwendungsfälle beschränken.


Rheinwerk Computing - Zum Seitenanfang

7.5.4Verschlüsselung (in der Cloud)Zur vorigen Überschrift

Wenn Sie sich auf die Angaben von Apple zur Verschlüsselung der Daten in der iCloud nicht verlassen wollen oder können, z. B. weil eine (gesetzliche) Vorgabe Sie daran hindert, personenbezogene Daten außerhalb des Geltungsbereiches des Bundesdatenschutzgesetzes zu speichern, bleibt Ihnen nichts anderes übrig, als die Daten »zu Fuß« zu verschlüsseln, bevor Sie diese in der iCloud speichern.

Das Mittel der Wahl dafür ist die CommonCrypto-Bibliothek aus dem Security Framework. Leider ist CommonCrypto denkbar schlecht dokumentiert. Die Xcode-Dokumentation dazu hält lediglich Man-Pages für den Programmierer bereit. Man-Pages sind Relikte aus der Steinzeit der Computer und werden üblicherweise über das Terminal eines Unix-Systems angesprochen. Freundlicherweise enthält die Xcode-Dokumentation zu CommonCrypto auch einen entsprechenden Hinweis:

This document is a Mac OS X manual page. Manual pages are a command-line technology for providing documentation. You can view these manual pages locally using the man(1) command. These manual pages come from many different sources, and thus, have a variety of writing styles.

For more information about the manual page format, see the manual page for manpages(5).

Leider enthält das Beispielprojekt zur Verwendung von CommonCrypto einige Fehler bei der Verwendung der kryptografischen Funktionen und ist nicht mehr auf einem aktuellen Stand, so dass Sie als Programmierer leider komplett im Regen stehen, wenn Sie sich mit der manuellen Verschlüsselung von Daten unter iOS beschäftigen möchten. Money Quote für alle Krypto-Kenner aus der Datei CommonCryptor.h:

Another option for block ciphers is Cipher Block Chaining, known as CBC mode. When using CBC mode, an Initialization Vector (IV) is provided along with the key when starting an encrypt or decrypt operation. If CBC mode is selected and no IV is provided, an IV of all zeroes will be used.

Zur Verschlüsselung von Daten in der iCloud bietet sich die symmetrische Verschlüsselung mit dem Algorithmus AES an. AES ist ein Industriestandard und in den USA für alle Geheimhaltungsstufen zugelassen. Symmetrische Verschlüsselung bedeutet, dass der Vorgang des Verschlüsselns mit demselben Schlüssel erfolgt wie der des Entschlüsselns. Dies ist die bereits aus der Antike bekannte »natürliche« Form der Kryptografie.

Innerhalb einer App, die ihre Daten selbst ver- und entschlüsselt, ist symmetrische Verschlüsselung eine gute Wahl. Der dieser Methode inhärente Nachteil, dass für beide Operationen (also für die Verschlüsselung sowie für die Entschlüsselung) derselbe Schlüssel vorhanden sein muss, ist in einer App kein Problem. Bei der Übertragung von verschlüsselten Daten an Dritte im Internet (z. B. über verschlüsselte E?Mails) ist das Problem des Schlüssels erheblich, so dass bei solchen Konstellationen die asymmetrische Verschlüsselung zum Einsatz kommt, bei der Ver- und Entschlüsselung über verschiedene Schlüssel erfolgen.

Anschließend fügen Sie eine neue Subklasse von NSObject Klasse zum Projekt hinzu. In dieser Klasse werden Sie im Folgenden die gesamte Kryptografiefunktionalität implementieren. Geben Sie der Klasse den Namen CryptoUtils, und fügen Sie in der Headerdatei die folgenden Propertys und Methoden ein:

#import <Foundation/Foundation.h>
@interface CryptoUtils : NSObject
-(NSData *)encryptData:(NSData *)clearText;
-(id)initWithPassword:(NSString *)thePassword;
@property (retain) NSData *salt;
@property (retain) NSData *iv;
@property (retain) NSString *password;
@property (retain) NSData *cryptKey;
@end

Listing 7.31 Die Headerdatei von »CryptoUtils«

Die vier Propertys der Klasse sind die essenziellen Bestandteile für die sichere Verschlüsselung von Daten mit AES. Das Passwort (password) ist das vom Benutzer vergebene Passwort, aus dem sich der Schlüssel für die Verschlüsselung ableitet. Aus Abschnitt 7.4.1, »Authentisierung«, wissen Sie bereits, dass die Verwendung des reinen Passwortes Gefahren birgt. Daher wird das Passwort mit einem Salt-Wert versehen (siehe dazu auch die Top 25). Die auch in CommonCrypto verfügbare Password-Based Key Derivation Function 2 (PBKDF2) erzeugt aus dem aus Salt und Passwort bestehenden Wert dann den eigentlichen Schlüssel (cryptKey), der bei der Ver- und Entschlüsselung an CommonCrypto übergeben wird.

PBKDF2

Die Password-Based Key Derivation Function 2 ist seit iOS 5 Bestandteil von iOS. PBKDF2 erzeugt durch das wiederholte Anwenden einer Hashfunktion auf die Kombination von Salt und Passwort einen Schlüssel, der wesentlich besser gegen Brute-Force-Angriffe geschützt ist als das reine Passwort (mit Salt), da ein Angreifer diese Iterationen alle rückwärts durchführen müsste, um aus dem Schlüssel auf das ursprüngliche Passwort schließen zu können.

Die Anzahl der Wiederholungen der Hashfunktionen ist bei CommonCrypto frei definierbar. Ein guter Wert sind 10.000 Runden. Diese benötigen auf einem iPhone 4 ca. 900 Millisekunden. Das ist ein guter Wert, wenn Sie dazu die gestiegene Sicherheit gegenüber Passwort-Crackern bedenken. Sie können über die Funktion CCCalibratePBKDF auch den umgekehrten Weg gehen und ermitteln, wie viele Runden pro Millisekunden Rechenzeit herauskommen. Zum einen führt das aber bei langsameren Systemen zu entsprechend weniger Runden, zum anderen müssen Sie den Wert bis zur Entschlüsselung mitführen, da Sie sonst den für die Entschlüsselung benötigten Key nicht mehr erzeugen können.

AES ist eine Blockchiffre, was bedeutet, dass die zu verschlüsselnden Daten in Blöcke aufgeteilt werden. Der Modus der Wahl bei AES, weil er die höchste Sicherheit bietet, ist der Cipher Block Chaining Mode (CBC) [Anm.: https://secure.wikimedia.org/wikipedia/de/wiki/Cipher_Block_Chaining_Mode] . Dieser Modus teilt den zu verschlüsselnden Klartext in Blöcke auf und verschlüsselt jeden Block mit dem eigentlichen Schlüssel und dem Ergebnis der Verschlüsselung des vorhergehenden Blocks. Da es beim ersten Block einer Verschlüsselung keinen vorherigen Block gibt, müssen Sie für diesen Block einen zufälligen Wert verwenden. Dieser Wert ist der sogenannte Initialisierungsvektor (IV), der in CryptoUtils in der gleichnamigen Property abgelegt wird.

Salt und IV – geheim oder nicht?

Das Salt und der Initialisierungsvektor sind zwar essenzielle Parameter für eine wirksame Verschlüsselung, entgegen der häufig vertretenen Meinung gibt es aber keinen Grund, beide Werte geheim zu halten.

Sie müssen also weder das Salt noch den Initialisierungsvektor selbst verschlüsselt aufbewahren oder unzugänglich machen. Die Kenntnis eines oder beider Daten bringt einem Angreifer keinerlei Vorteil, so dass Sie vollkommen sorglos damit umgehen können. Auch ist die Quelle der Daten unerheblich. Verwenden Sie beliebig zufällige Werte für beides.

Die einzige wirklich wichtige Anforderung ist, dass Sie diese Werte überhaupt persistent speichern, denn ansonsten werden Sie die damit verschlüsselten Daten nicht mehr entschlüsseln können.

Die Implementierung von CryptoUtils beginnt mit den folgenden Anweisungen:

#import "CryptoUtils.h"
#import <CommonCrypto/CommonKeyDerivation.h>
#import <CommonCrypto/CommonCryptor.h>
NSUInteger const PBKDFRounds = 10000;
@implementation CryptoUtils
[...]

Listing 7.32 Der Kopf der Implementierung von »CryptoUtils«

Die Headerdatei CommonKeyDerivation.h enthält das Interface für die PBKDF2-Funktion. Der AES-Algorithmus ist in CommonCryptor.h deklariert.

Die Methode initWithPassword: übernimmt das Benutzerpasswort für die Verschlüsselung, erzeugt mit der Funktion SecRandomCopyBytes einen zufälligen Initialisierungsvektor und ein zufälliges Salt und weist Passwort, Initialisierungsvektor und Salt den entsprechenden Propertys zu:

- (id)initWithPassword:(NSString *)thePassword
{
self = [super init];
if (self) {
NSMutableData *theData = [NSMutableData
dataWithLength:kCCBlockSizeAES128];
SecRandomCopyBytes(kSecRandomDefault,
kCCBlockSizeAES128, theData.mutableBytes);
self.iv = theData;
theData = nil;

theData = [NSMutableData
dataWithLength:kCCBlockSizeAES128];
SecRandomCopyBytes(kSecRandomDefault,
kCCBlockSizeAES128, theData.mutableBytes);
self.salt = theData;
theData = nil;
self.password = thePassword;
}
return self;
}

Listing 7.33 Die Methode »initWithPassword:«

kCCBlockSizeAES128 ist die Größe eines Blocks bei der Verschlüsselung mit AES, und kSecRandomDefault ist der empfohlene Zufallsgenerator unter iOS. Die eigentliche Verschlüsselungsoperation erfolgt in der Methode encryptData: über den Aufruf CCCrypt:

- (NSData *)encryptData:(NSData *)clearText {
[self createKey:[self.password
dataUsingEncoding:NSUTF8StringEncoding]];

// Puffer für Ciphertext
NSMutableData *cipherData = [NSMutableData
dataWithLength:clearText.length + kCCBlockSizeAES128];

// Länge des Ciphertextes
size_t cipherLength;

// Durchführen der Verschlüsselung
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
self.cryptKey.bytes,
self.cryptKey.length,
self.iv.bytes,
clearText.bytes,
clearText.length,
cipherData.mutableBytes,
cipherData.length,
&cipherLength);

if(cryptStatus){
NSLog(@"Something terrible during encryption
happened!");
} else {
NSLog(@"Ciphertext length: %i", [cipherData length]);
}
return cipherData;
}

Listing 7.34 Die Implementierung der Methode »encryptData:«

Der Aufruf der Methode createKey: erzeugt in einer noch zu implementierenden Methode aus dem Benutzerpasswort per PBKDF2 einen sicheren Schlüssel. Das Objekt cipherText ist der Zielpuffer, in den CCCrypt die verschlüsselten Daten schreibt. Die Variable cipherLength nimmt die Länge der von CCCrypt verarbeiteten Daten auf.

Die Funktion CCCrypt selbst übernimmt 12 Parameter:

  • die gewünschte Operation (hier: Verschlüsselung)
  • den gewünschten Algorithmus (hier: AES128)
  • Angaben zum Padding von Daten (siehe den folgenden Kasten)
  • einen Zeiger auf den Schlüssel
  • die Länge des Schlüssels
  • einen Zeiger auf den Initialisierungsvektor
  • die Länge des Initialisierungsvektors
  • einen Zeiger auf die zu verschlüsselnden Daten (den »Klartext«)
  • die Länge der zu verschlüsselnden Daten
  • einen Zeiger auf den Puffer für die verschlüsselten Daten (den »Ciphertext«)
  • die Länge des Puffers für den Ciphertext
  • die Adresse der Variablen für die Länge der verarbeiteten Daten

Padding

Bei der Verwendung von Blockchiffren wird der Klartext in Blöcke aufgeteilt, bei AES in Blöcke von 16 Bytes. Ist der Klartext nicht durch 16 teilbar, bleibt ein Rest, der keinen ganzen Block auffüllt. Dieser Rest fällt bei der Verschlüsselung heraus. Daher muss man den nur teilweise aufgefüllten Block auffüllen, so dass er korrekt verschlüsselt wird. Dieses Auffüllen nennt sich Padding. CCCrypt führt das Padding automatisch durch, wenn die Option kCCOptionPKCS7Padding gesetzt ist.

Die Methode zum Erzeugen eines sicheren Schlüssels ist createKey:

- (BOOL)createKey:(NSData *)key{
NSMutableData *localKey = [NSMutableData
dataWithLength:kCCKeySizeAES128];
int result = CCKeyDerivationPBKDF(kCCPBKDF2,
self.password.UTF8String,
self.password.length,
self.salt.bytes,
self.salt.length,
kCCPRFHmacAlgSHA1,
PBKDFRounds,
localKey.mutableBytes,
localKey.length);
if(kCCSuccess){
NSLog(@"Fehler beim Erstellen des Schlüssels:
%d", result);
}
self.cryptKey = localKey;
return YES;
}

Listing 7.35 Die Methode »createKey:«

Der Aufbau der Methode entspricht der Methode encryptData:. Die Funktion CCKeyDerivationPBKDF übernimmt die folgenden neun Parameter:

  • die gewünschte Funktion (hier: PBKDF2)
  • das Passwort
  • die Länge des Passworts
  • einen Zeiger auf das Salt
  • die Länge des Salts
  • die zu verwendende Funktion (hier: SHA1, da in diesem Zusammenhang vollkommen ausreichend)
  • die Anzahl der Runden
  • einen Zeiger auf den Puffer für den Schlüssel
  • die Länge des Schlüssels

Der Aufruf der Methode createKey: in der Methode encryptData: übergibt als Parameter das Benutzerpasswort, abgelegt in der Property password des Objekts:

[self createKey:[self.password 
dataUsingEncoding:NSUTF8StringEncoding]];

Die Methode createKey legt den erzeugten Schlüssel anschließend in der Property cryptKey ab.

Um die Klasse CryptUtils zu verwenden, importieren Sie die Interface-Datei in der Implementierung des AppDelegates:

#import "CryptoUtils.h"

Anschließend erzeugen Sie ein Objekt von CryptoUtils, übergeben ihm ein Passwort und zu verschlüsselnden Text und können anschließend den Ciphertext samt Salt und Initialisierungsvektor in der iCloud ablegen:

[...]
CryptoUtils *theCrypt = [[CryptoUtils alloc] initWithPassword:@"4711"];
NSData *ciphertext = [theCrypt encryptData:[theLocalText dataUsingEncoding:NSUTF8StringEncoding]];
[cloudStore setData:theCrypt.salt forKey:@"Salt"];
[cloudStore setData:theCrypt.iv forKey:@"IV"];
[cloudStore setData:ciphertext forKey:@"Secret"];
[...]

Listing 7.36 Verschlüsselte Daten in der iCloud

Diesen Code fügen Sie in die GDC-Funktion in der Methode application didFinishLaunchingWithOptions: ein, nachdem Sie das Funktionieren des iCloud-Zugangs verifiziert haben.

Dadurch, dass Salt und Initialisierungsvektor nun auch in der iCloud liegen, haben Sie das Problem der Aufbewahrung umgangen. Zum Entschlüsseln der Daten benötigen Sie lediglich das korrekte Benutzerpasswort. Die Entschlüsselung erfolgt analog zur Verschlüsselung über die Funktion CCCrypt, wobei der erste Parameter nicht kCCEncrypt, sondern kCCDecrypt ist.

Hausmeistertätigkeiten

Das vorangegangene Beispiel wendet zwar Verschlüsselung an, ist aber nicht auf einen gesicherten Betrieb hin optimiert. Die sensiblen Daten (Klartext und Passwort), die in den Propertys von CryptoUtils liegen, befinden sich so lange im Speicher, wie ein Objekt vom Typ CryptoUtils existiert. Auch würde mangels Event-Handling ein Fehler beim Erstellen des PBKDF2-gesicherten Schlüssels dazu führen, dass die Verschlüsselungsoperation einfach mit dem ungesicherten Schlüssel durchgeführt würde. Achten Sie beim Programmieren einer App für besondere Sicherheitsanforderungen daher auf solche Aspekte. Wenden Sie die Designprinzipien aus Abschnitt 7.3.3, »Generische Designgrundsätze«, konsequent an, und Sie sind auf einem guten Weg.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück




Copyright © Rheinwerk Verlag GmbH, Bonn 2014
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de


  Zum Katalog
Zum Katalog: Apps programmieren für iPhone und iPad






Neuauflage: Apps programmieren für iPhone und iPad
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Einstieg in Objective-C 2.0 und Cocoa






Einstieg in Objective-C 2.0 und Cocoa


Zum Katalog: Spieleprogrammierung mit Android Studio






Spieleprogrammierung mit Android Studio


Zum Katalog: Android 5






Android 5


Zum Katalog: iPhone und iPad-Apps entwickeln






iPhone und iPad-Apps entwickeln


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo