Java und Kryptographie Inhaltsverzeichnis 1 Einleitung 2
Transcrição
Java und Kryptographie Inhaltsverzeichnis 1 Einleitung 2
Java und Kryptographie Markus Dauberschmidt, [email protected] 10. April 2009 Inhaltsverzeichnis 1 Einleitung Kryptographie! Kaum ein anderer Begri hat in den letzten Jahren eine solche Verbreitung in weiten Schichten der Bevölkerung erreicht. Sei es bedingt durch den Bundestrojaner (-> Durchsuchen der lokalen Festplatte / Furcht vor Durchsuchungen von privaten Daten), den erhöhten Bedarf von Unternehmen an der Sicherung ihrer unternehmenskritischen Daten (-> Spionage, Abhören, Diebstahl) oder XYZ - das Thema Kryptographie hat zunehmend an Bedeutung gewonnen. Was sich hinter dem Begri verbirgt, welche Umsetzungen es in der IT gibt und wie man auf einfache Art und Weise Kryptographie in neue und bestehende Java-Programme intergriert werden kann soll der vorliegende Text beleuchten. 2 Wozu eigentlich Kryptographie? Der Wunsch des Menschen Geheimnisse vor den Augen neugieriger Mitmenschen zu verstecken geht bis in die Frühzeit der Menschheit zurück. Seien es die Ägypter, deren Hyroglyphen als eine erste Art von kryptographie gelten mögen oder die alten Römer, seit jeher versuchte der Mensch seine Gemeimnisse zu schützen. In späteren Jahrhunderten gab der Kryptographie auch gerade im Bereich der Kriegsführung eine immer bedeutende Rolle zu und auch eine Maria Stuart versuchte sich mittels Kryptographie vor der drohenden Enthauptung zu schützen - was allerdings schluÿendlich mislang (weil die Kryptographie zu schwach war). Gerade im letzten Jahrhundert hat der Bereich der Verschlüsselung eine gerade zu rasante Entwicklung hinter sich. Zu Zeiten des 1. und 2. Weltkrieges traten Verschlüsselungsmaschinen wie eine allseits bekannte Enigma oder eine XYZ in das Licht der Öentlichkeit und die zunehmende Verbreitung der IT sorgten für einen rasanten Schub mit der Entwicklung. Brilliante Köpfe entwickeltn neue Verfahren Daten zu verschlüsseln, die asymmetrische Kryptographie, welche auch heute nohc die Basis für jede Art von sicherer Kommunikatin ist (Email, Web, etc.) und schufen Lösungen für das alte Problem des sicheren Schlüsselaustauschs (Die Helmann Schlüsselaustausch). Die zunehmende Globalisierung der Wirtschaft sorgte für einen ebenfalls gestiegenen Bedarf an Lösungen für den sicheren Austausch von Informationen. Hierbei ist der Angreifer nicht nur ein konkurrierendes Unternehmen, sondern immer häug auch die nachrichtendienste fremder Staaten, (die dann die gefundenen Informationen jedoch logischerweise den einheimischen Unternehmen zur Verfügung stellen). Als ein Beispiel mag hierfür der Wirtschafts-Spionage-Fall bei der Firma Siemens gelten, der den Abschluÿ eines Vertrages über den ICE für China zum Scheitern brachte, da es dem französischen Geheimdienst gelang ein Angebot auf einer der WAN-Strecken abzufangen und dadurch den französischen Konkurrenten TGV in die lage versetzte, dem Kunden ein besseres Last-minute-Angebot zu machen. Immer häuger liest man auch von gezielten Versuchen, dass versucht wird Aussendienstmitarbeitern an Bahnhöfen und Flughäfen das mobile Gerät (Notebook oder PDA) zu entwenden um über die darauf gespeicherten Daten wiederum Geschäftsvorteile zu bekommen. Wohl dem der vorgesorgt hatte und die Geräte durch eine lokale Verschlüsselung (Festplattenverschlüsselung, File & Folder-Verschlüsselung o.ä.) abgesichert hatte. Doch nicht nur in der Industrie erfreut sich die Kryptographie steigender Beliebtheit, auch der private Nutzer setzt immer häuger Kryptographie ein. Sei es zur Verwaltung seiner Passwörter für die diversen Online-Shops und Foren oder zum Austausch von eher privatgen Nachrichten mit Freunden 1 und Bekannten, der Trend geht immer mehr zu einer sichren Lösung, anstatt zu Plain-Text-Mails bzw. Textdateien. Natürlich hat auch der .com Hype und der seitdem wachsende Trend zu Online-Shopping sein übriges getan. Niemand würde heute freiwillig mehr seine Bankdaten oder seine Kreditkartennummer unverschlüsselt an einen Online-Shop senden. Die Nutzung von (starker) Kryptography durch Dienstleister und Shops ist mittlerweile zu einer Grundvoraussetzung für ein tragendes Geschäftsmodell geworden. Doch unter Kryptographie versteht man nicht nur die reine Datenverschlüsselung, sondern auch die Integritätsüberprüfung der Daten. Mit Hilfe von sog. digitalen Signaturen ist es heute möglich die Unversehrheit bzw. Unverfälschtheit einer Information zu verizieren. So können sich zum Beispiel der Bankkunde sicher sein, dass sein Überweisungsauftrag nicht auf dem weg zur Bank unerkannt verändert wurde und nun ein falscher Betrag auf einem fremden Konto landet anstatt auf dem ursprünglich beabsichtigeten Konto. 3 Symmetrische und asymmetrische Verschlüsselung Gemeinhin kann man zwei groÿe Klassen der Verschlüsselung unterscheiden: Die symmetrische und asymmetrische Verschlüsselung 3.1 Symmetrische Verschlüsselung Bei der symmetrischen Verschlüsselung kennen sowohl Sender als auch Empfänger das Geheimins (Schlüssel), welches zum Verschlüsseln der Daten verwendet wurde. Man spricht hier auch von einem shared secret. Zum Entschlüsseln kommt der gleiche Schlüssel zum Einsatz wie auch zum Entschlüsseln. Grak Die symmetrische Verschlüsselung selbst kann man wiederum in 2 groÿe Klassen einteilen: StreamCiphren und Block-Ciphren. Diese beiden Verfahren arbeiten grundsätzlich verschieden: Block-Cipher Wie der Name schon suggeriert, werden bei einem Block-Cipher jeweils Blöcke fester Länge der Eingabe verschlüsselt. Jeder Block wird dabei vom Grundgedanken her für sich alleine verschlüsselt. Ist der letzte Block kleiner als die Blockgröÿe des Ciphers, so muss ein sog. Padding erfolgen, dass heisst der Block muss bis zur benötigten Gröÿe mit Pad-bytes aufgefüllt werden. Für das Padding gibt es verschiedene Standards (PKCS7, ....) die jeweils genau festlegen, ob es sich dabei um Nullbytes oder Wechselfolgen handelt oder ob diese PadBytes ein anderes Format haben. Arbeits-Modi Wird streng nach dem Modus Block rein - Block raus vorgegangen und jeder Block für sich allein genommen verschlüsselt, spricht man von ECB - Electronic Code Book Mode. Das groÿe Problem hierbei ist, dass gleiche Eingabeblöcke auch immer gleiche Ausgabeblöcke produzieren und damit den Ciphertext anfällig für z.B. statistische Analysen machen! Abbildung 1: Arbeitsweise des ECB Mode 2 Um dies zu verhindern bzw. zu erschweren gibt es verschiedene andere Arbeits-Modi von denen ich den CBC vorstellen möchte. CBC steht für Cipher Block Chaining und bedeutet im Endeekt, dass jeder Klartext-Block zunächst noch mit dem vorherigen Cipherblock XOR verknpüft wird, bevor er verschlüsselt wird. Auf diese Weise ist das Ergebnis also immer vom vorherigen Block abhängig und Cipher-Text Analysen werden stark erschwert. Ein Problem existiert natürlich am Anfang: Womit wird der allererste Block verknüpft? Hier kommt der sogenannte IV der Initialisierungsvektor ins Spiel. Dieser liefert die Daten mit denen der erste Klartextblock XOR verknüpft wird, bevor er dann verschlüsselt wird. Der IV muss nicht geheim gehalten werden, sollte aber möglichst zufällig gewählt werden (zum Beispiel abgeleitet aus der aktuellen Uhrzeit, einer Zufallszahl, etc.) Abbildung 2: Arbeitsweise des CBC Mode Sind die Blöcke bei der Ver- und Entschlüsselung voneinander abhängig, können sich Bitfehler bei der Übertragung natürlich katastrophal auswirken. Beim CBC ist es jedoch so, dass ein Bitfehler im Block N immer nur den nachfolgenden Block N + 1 verfälscht, sich Fehler als nicht beliebig lange fortpanzen. Neben diesen beiden Modi gibt es weitere die aus der Blockverschlüsselung de facto eine StromVerschlüsselung machen. Hierzu zählen zum Beispiel die Modi OFB (Open Feedback), CFB (Cipher Feedback) und CTR (Counter Mode). Mehr zu diesen Modi ndet man unter ........... Die bekanntesten Vertreter der Klasse der Blockchiren sind AES (Rijndahl), DES, 3DES, Twosh und Blowsh Der Rijndahl wurde im Rahmen einer NIST Ausschreibung zum Sieger eines Wettbewerbes gewählt bei dem es darum ging einen Nachfolger für den bis dahin dominierenden Verschlüsselungsalgorithmus DES bzw. 3DES zu nden. Rijndahl hat sich gegen eine Reihe von Algorithmen von bekannten Persönlichkeiten der Kryptowelt (Ron Rivest, Bruce Schneier) durchgesetzt und wurde dadurch der neue Standard (AES = Advanced Encryption Standard) was symmetrische Verschlüsselung angeht. AES wird seitdem einen kometenhaften Aufstieg hinter sich und wird heute in so gut wie jeder Anwendung unterstützt, die Verschlüsselungsmöglichkeiten bietet. Eine exzellente Erläuterung wie der AES funktioniert ndet sich unter http : //www.f ormaestudio.com/rijndaelinspector/archivos/RijndaelA nimationv 4e ng.swf Stream Cipher: Im Gegensatz zu einem Block-Chire, muÿ bei einem Strom-Chire nicht darauf gewartet werden, dass sich genügend Klartext-Daten angesammelt haben, so dass ein Block verschlüsselt werden kann, sondern die Verschlüsselung kann sofort beim ersten Bit begonnen werden. Hierdurch ergibt sich ein kleiner Performance-Vorteil der Strom-Chiren besonders für Echtzeitübertragungen, wie beispielsweise im Mobilfunk zur Verschlüsslung von Gesprächsdaten sinnvoll macht. Die Klartext-Daten werden hierbei mit einem Bitstrom (auch Schlüsselstrom genannt) XOR verknüpft. Die Entwicklung des Schlüsselstroms hängt dabei von de bisher verschlüsselten Daten ab. Man kann daher eine Strom-Chire in etwa mit einer State-Machine vergleichen. Strom Chiren können sehr sicher verwendet werden, jedoch nur wenn beachtet wird, dass der selbe Startzustand (IV) nie mehrfach verwendet wird. Ein Stream-Cipher kann hier durch theoretisch auch die 3 ideale Sicherheit eines One-Time-Pad erreichen. Einem One-Time-Pad (OTP) liegt kein fester Algorithmus zugrunde, sonder der Schlüsselstrom wird komplett zufällig gebildet und basiert nicht auf einem wie auch immer gearteten Algorithmus. Da durch die Zufälligkeit kein Ansatz gegeben ist wie der Schlüssel ermittelt werden kann, gitl ein OTP als unbrechbar. In der Praxis werden OTPs jedoch so gut wie nie verwendet, da die wirklich zufällige Generierung von ausreichend langen Zufallszahlenketten alles andere als trivial ist. Alle Zufallszahlen-Generatoren, deren Zufälligkeit rein durch Software-Algorithmen bestimmt wird, sind pseudo-random. Echte Zufallszahlen erzeugt man durch externe Einüsse, wie z.B. Sensoren die Spannungsschwankungen oder Temperaturunterschiede an Motherboard-Komponenten miteinbeziehen. Auf diesem Gebiet wird aktiv geforscht. Einige interessante Projekte nden sich in: .......... Allen Verfahren der symmetrischen Verschlüsselung ist gemein, dass sie in der Regel eine sehr hohe Verschlüsselungs und Entschlüsselungs-Geschwindigkeit erreichen, dass heisst auch das Verschlüsseln von groÿen Datenmengen ist hiermit performant möglich. Dies liegt darin begründet, dass normalerweise für die Verschlüsselungsvorgänge relativ einfache arithmetrische Operationen wie Multiplikationen, Additionen verwendet werden, sowie Ersetzungen der Daten vorgenommen werden (Substitutionsschritte und Diusion). Ein weiterer Vorteil, der auch die hohe geschwindigkeit begründet ist darin zu sehen,d ass aufgrund der Einfachheit der algebraischen Umformungen der Verschlüsselungalgorithmus in de rRegel auch sehr gut in hardware umgesetzt werden kann und hiermit durch entsprechende schaltungsoptimiereungen eine nochmals höhere Geschwindigkeit erzielt werden kann. Die Schlüssellängen bei Block-Chiren sind relativ kurz mit in der Regel 128, 192 oder 256 Bit schlüssellänge. In der Natur des shared secrets, welches dem Empfänger und dem Sender der Nachricht vorliegen muss liegt aber auch das gröÿte problem der symmetrischen Kryptographie begründet. Das gemeinsame Geheimnis will zunächst auf einem sicheren Weg zwischen den beiden Kommunikationspartnern ausgetauscht werden. Erlangt ein Angreifer bei diesem Austauschprozess Kenntnis von dem geheimen Schlüssel ist die Verschlüsselung zwecklos, da der Angreifer die Daten entschlüsseln kann. (unter gewissen Rahmenbedinungen) Eine Abhilfe für dieses Dilemma fand im Jahre 1976 das Forscherduo Die-Hellman mit der Erndung des Die-Hellman Algorithmuses zum sicheren Schlüsselaustausch (siehe ....). Diese Forschungsarbeiten begründete den Startschuÿ für die 3.2 Asymmetrische Verschlüsselung Der grundlegende Unterschied der asymmetrischen Verschlüsselung zur symmetrischen Verschlüsselung besteht darin, dass für die Ver- und Entschlüsselung zwei unterscheidliche Schlüssle zum Einsatz kommen. Man spricht von einem Schlüsselpaar und von dem privaten Sschlüssel und dem öentlichen Schlüssel. In Anlehnung an diese Namensgebung bezeichnet man die asymmetrische Verschlüsselung auch häug als private/public key cryptography. Für die konsequente Nutzung der private/public cryptography wird eine sog. PKI (Private/Public Key Infrastrucure) benötigt. Den Teil des Schlüssels der zum Entschlüsseln der Daten verwendet wird, bezeichnet man als Private Key und der wird, wie der Name schon sugeriert, geheim gehalten. Der Schlüsselteil mit dem die Daten an den Besitzer des privat eKeys verschlüsselt werden bezeichnet man als public key und dieser ist, wie ebenfalls am Namen ersichtlich, öentlich. Häug werden die öentlichen Schlüssel in sogenannten Key Respositories im Internet hinterlegt, so dass jederman mit der entsprechenden Verschlüsselungsoftware (z.B. PGP) in der Lage ist, verschlüsselte Daten zu verschicken (...). Im Gegensatz zur symmetrischen Verschlüsselung setzt die asymmetrische Verschlüsselung auf komplexe Algebra-Operationen zur Verschlüsselung. Einige Keywords in diesem Zusammenhang sind diskreter Logarithmus, kleiner Satz von Fermant, Exponentialfunktion sowie Modulo-Rechnungen. Eine asymmetrische Verschlüsselung von Daten ist daher häug wesentliche teurer in der Ausführung als ihr symmetrischer Gegenpart. Ebenso werden bei der symmetrischen Verschlüsselung weitaus längere Schlüssellängern verwendet (i.d. R. mindestens 1024 Bit, häug auch 2048, selten auch 4096 Bit). Für die Verschlüsselung der Daten wird eine sogenannte Falltürfunktion verwendet, dass bedeutet die Errechnung eines Wertes Y aus einem Wert X (die Verschlüsselung/Hin-Richtung) ist sehr einfach möglich, die Zurückrechnung des Wertes X aus einem abgefangenen Wert Y jedoch so gut wie unmöglich - es sei denn man besitzt das Geheimnis (den private Key). Durch die verwendeten Mechanismen zur Verschlüsselung geht auch häug eine wesentliche Vergröÿerung der Daten einher. Nicht selten sind die asymmetrisch verschlüsselten Daten doppelt so groÿ wie die unverschlüsselten Rohdaten, was sich bei der Übertragung signkant auswirken kann. 4 Da wie bereits erwähnt, die asymmetrische Verschlüsselung von Daten auch wesentlich aufwändiger und langsamer ist, wird die asymmetrische Verschlüsselung in der Praxis daher häug nur auf relativ kleine Datenmengen angewandt. 3.3 Kombination von asymmetrischer und symmetrischer Verschlüsselung Um einerseits das Problem des sicheren Schlüsselaustauschs und andererseits eine hohe Verschlüsselungsgeschwindigkeit zu erreichen wernden in der Praxis häug asym. und sym. Kryptographie kombiniert. Die eigentliche Datenverschlüsselung der Nutzdaten geschieht mit einem symmetrischen Verfahren wie dem AES welches eine hohe Performanz bietet. Der hierfür verwendete Schlüssel wird aber dann wiederum stark asymmetrisch verschlüsselt. Häug gibt es auch noch den Fall, dass um die Sicherheit weiter zu erhöhen, der symmetrische Schlüssel nach regelmäÿigen Intervalen (z.B. 1 Stunde, 1 MByte Nutzdaten, o.ä.) gewechselt wird. 4 Der RSA-Algorithmus Erwähnt man den Begri asymmetrische Verschlüsselung, so muss konsequenterweise auch eine kurze Vorstellung des RSA-Algorithmus, welcher als die bekannteste Implementierung der asymmetrischen Kryptographie gelten darf und welcher heute nach wie vor in allen etablierten Verschlüsselungsprodukten verwendet wird. Da der Algorithmus eine so wichtige Basis für alle heutigen Themen wie S/MIME, SSL und TLS bildet, wird versucht im Folgenden die Funktionsweise kurz vorzustellen. Da für eine detaillierte Betrachtung der mathematischen Vorgänge und Beweise der Aktionen in diesem Artikel der Platz mangelt, sei für Interessierte auf die sehr guten Informationsquellen X,Y,Z verwiesen. Der RSA-Algorithmus wurde im Jahr 1974 von den amerikanischen Mathematikerns Ronald Rivest, Adi Shamir und Leonard Adleman am MIT entwickelt, deren Initialen auch seinen Namen bilden. Abbildung 3: Ronald Rivest (mi), Adi Shamir (li) und Leonard Adleman (ri) auf einem Photo von 1974 5 Er wurde in der Folgezeit zahlreichen Crypt-Analysen unterzogen, dass der Algorithmus aber nach wie eingesetzt wird, zeugt von der hohen Qualität bei der Entwicklung. Die Sicherheit des Verfahrens beruht auf dem Problem der Faktorisierung groÿer Zahlen in ihre Primfaktoren. Hierzu existieren heutzutage eziente Algorithmen aber nach wie ist dieses Problem so komplex, dass ein Brute Force Angri als bester Angri gilt. Im Kern funktioniert das Verfahren wie folgt. Für die Ver-/Entschlüsselung wird ein Schlüsselpaar benötigt, der private und public key. Um verschiedene Vorgänge und Szenarien in der Welt der Kryptographie zu beschreiben, bedienen wir uns im Folgenden Ihrer beiden bekanntesten Vertreten, dem imaginären Paar Alice und Bob. Alice und Bob haben den Wunsch sicher miteinander zu kommunizieren. Ihnen gegenüber stehen Mallory und Eve (von Eavesdroppen, engl. abhören), zwei Gegenspieler die nichts unversucht lassen die Kommunikation von Alice und Bob in Erfahrung zu bringen oder zu verfälschen oder zu unterbinden. Um das RSA-Schlüsselpaar zu generieren überlegt sich Alice zwei Primzahlen p und q. Für das Verfahren ist es wichtig, dass es sich um 2 Primzahlen handelt und das diese relativ groÿ sind. Als Groÿ kann man Primzahlen ansehen die 100 und mehr Dezimalstellen besitzen. Um das Beispiel nachvollziehbar zu halten wählen wir für unsere beiden Primzahlen die Zahlen p = 47 und q = 71. Nun wird der Exponent N (auch Modulus) nach der Formel N := p · q berechnet. In unserem Beispiel ist N := 47 · 71 = 3337. Die Schlüssellänge eines RSA-Keys bezieht sich auf die Länge dieser Zahl N in Binärdarstellung. Die Länge einer Zahl erreichnet sich, wie bekannt indem der Logarithmus dualis der Zahl errechnet wird und auferundet wird. In unserem Beispiel wäre die Schlüssellänge dlog2 (47 · 71)e = 12 RSA-Schlüssel haben in der Praxis wie oben erwähnt mindestens 1024 Bit Schlüssellänge... Als dann wird mit Hilfe der Euler'schen Psi-Funktion die Zahl Ψ(N ) = (p − 1) · (q − 1) errechnet. In unserem Beispiel ist Ψ(N ) = 46 · 70 = 3220. Nun wählt man frei eine Zahl e die gröÿer als 1 jedoch kleiner als Ψ(N ) ist: e := x ∈ N : 1 < x < Ψ(N ) Diese Zahl bezeichnet man als Public Exponent. Für unser Beispiel wählen wir die Zahl 79. Wie der Name suggeriert, muss diese Zahl nicht geheim gehalten werden. Wählt man sie geschickt, so kann hierdurch eine deutliche Beschleunigung des Verfahrens ohne Einbusen bzgl. der Sicherheit erreicht werden. In der Praxis wählt man für den Public Exponent häug die Zahl 65537. Das Zahlenpaar Public Exponent und Modulus ist der öentliche Schlüssel, der Public Key. In unserem Beispiel ist der Public Key also aus den Zahlen 3337 und 79 gebildet. Um den privaten Schlüssel zu errechnen, wird das multiplikative Inverse d zu e errechnet e·d=1 mod Ψ(N ) In der Praxis wird zur Bestimmung von d häug der erweiterte Euklidische Algorithmus (→ Bestimmung des GGT) verwendet. d ist hierbei nun der Private Exponent der geheim gehalten wird. Die Kombination aus d und N bildet den Private Key. In unserem Beispiel ist der Private Key das Zahlenpaar 3337 und 1019. Die Zahlen Ψ(N ), p und q müssen nach der Berechung des Schlüsselpaare sicher gelöscht werden, da mit Kenntnis dieser 3 Zahlen der Schlüssel erneut errechnet werden kann. Um Daten zu verschlüsseln geht man nun nach folgender Formel vor: ci := mei mod N wobei c der entstehende Ciphertext und m der Klartextblock ist, der verschlüsselt werden soll. Um eine gegebene Nachricht M zu verschlüsseln wird sie zunächst so in gleichgroÿe Blöcke m1 , m2 , . . . , mi zerlegt, dass der Wert des Blockes jeweils kleiner als der Modulus N ist. Trivialerweise könnten z.B. die ASCII-Zeichennummern von den Buchstaben des Klartextes als Blöcke m1 , m2 , . . . , mi verwendet werden. 6 Der Empfänger kann aus dem Ciphertext c nun wieder den Orginaltextblock m erstellen indem er den Vorgang quasi umkehrt. mi := cdi mod N ) Das Ganze nun an einem Beispiel: Wir haben den folgenden Plaintext gegeben: Hello world!. Repräsentiert als Folge von gleichgroÿen Blöcken der ASCII Werten ergibt dies: 072 101 108 108 111 032 087 111 114 108 100 033. Diese Zahlen sind alle kleiner als under Modulus N mit 3337. Der erste Buchstabe unseres Plaintextes verschlüssel sich zu c1 = me1 mod N = 727 9 mod 3337 = 285 Analog für alle Klartextblöcke durchgeführt ergibt sich am Schluÿ der Ciphertext: 285, 1113, 1795, 1795, 2237, 1379, 1848, 2237, 2560, 1795, 1287, 1260 Es fällt auf, dass hier jeder gleiche Buchstabe im Plaintext durch den selben Ciphertext repräsentiert wird. In der Praxis wird so verfahren, dass die Nachricht asymmetrisch mit z.B. AES-128 im CBC verschlüsselt wird und nur der Encryption-Key/Session-Key für AES tatsächlich mit RSA verschlüsselt wird. Zum Entschlüsseln rechnen wir: m1 = cd1 mod N = 2851 019 mod 3337 = 72 usw. 5 Digitale Signatur Mit Hilfe einer Digitalen Signatur ist es möglich die eingangs erwähnte Verikation von übermittelten Daten durchzuführen. Die Durchführung ist hierbei überraschend einfach: Die Exponenten beim Verschlüsseln und Entschlüsseln werden vertauscht: Signierens := md mod N Überprüfung der Signaturm := se mod N Das heisst der Sender der Daten verschlüsselt (=signiert) diese mit seinem Private Key und der Empfänger ist in der Lage die Daten mit dem Public Key zu entschlüsseln. Dadurch dass die Entschlüsselung mit dem Public Key nur möglich ist, wenn der Private Key für die Verschlüsselung der Daten verwendet wurde und wiederum der Private Key per Denition nur der Eigentümer des Schlüssel hat, kann hiermit geschluÿfolgert werden, dass die Signatur vom Eigentümer des Private Key stammt (sogenannte Non Repudiation, engl. Nichtabstreitbarkeit). In der Praxis ist es daher wichtig die Schlüssel sofort zu wiederufen, sobald eine Kompromittierung festgestellt wird) Da aufgrund der Nachteile der asymmetrischen Kryptographie es jedoch extrem zeitaufwändig wäre die gesammten Daten mit dem Private Key zu verschlüsseln (=signieren) bedient man sich einer Abkürzung: Es wird ein Digest, ein digitaler Fingerabdruck der Daten genommen und dieser wird verschlüsselt. Dieser Digest wird mit Hilfe einer kryptographischen Hashfunktion gebildet. Das Ergebnis der Anwendung einer kryptographischen Hashfunktion auf einen Eingabetext ist eine in der Regel 16, 20 oder 32 Byte lange Hexzahlenfolge, der sogenannte Hash, welche den gesamten text repräsentiert. Das Besondere ist, dass auch nur das Verändern eines einzigen Bytes im Eingabetext (Ändern einer Zahl, Entfernen eines unsichtbaren Whitespaces o.ä.) zu einem völlig veränderten Hash führen wird. Naturgemäÿ muss es bei jeder Art von Hashfunktion welche ein Universum von Eingabewerten auf ein kleineres Ausgabeuniversum (2128 , 2160 , 2256 Zustände) zu Kollisionen kommen, dass heisst, dass mehrere Eingabewerte unabhängig voneinander den selben Hashwert erzeugen. Anhand der Signatur kann dann nicht mehr entschieden werden, welcher der Eingabetexte tatsächlich für die Signatur verwendet wurde. Damit eine Hashfunktion sinnvoll für eine Signatur eingesetzt werden kann, sollte es natürlich extrem schwierig sein, eine Hash-Kollision zu erzeugen, erst recht eine, bei der der zweite Klartext für einen Angreifer auch einen Vorteil bringt (Beispiel: Ersetzen des Wertes 100 EUR in einer Überweisung durch 1000 EUR). 7 Dieser Hash, der nun selbst sehr kurz ist, wird nun mit Hilfe des Private Keys signiert. Zur Verikation der Signatur geht der Empfänger wie folgt vor: Er bildet seinerseits den Hash über die Nachricht, entschlüsselt bzw. veriziert die Signatur mit Hilfe des Public Keys des Senders und vergleicht den erhaltenen Wert mit seinem eigenen errechneten Hashwert. Stimmen beiden Werte überein, so kann er sich (relativ) sicher sein, dass die Nachricht nicht verändert wurde, während eine Abweichung ein indiz dafür ist, das irgendetwas an den Daten manipuliert wurde. Es gibt heutzutage einige kryptographische Hashfunktionen unter denen man wählen kann. Der am häugsten eingesetzte Hash-Algorithmus ist seit vielen Jahren nach wie vor MD5, welcher wie der RSAAlgorithmus aus der Feder von Ron Rivest stammt. Nachdem jedoch einige Angrie bekannt geworden sind, die zu einer bewussten Kollision führen können, wird mittlerweile davon abgeraten, MD5 für neue Signaturen einzusetzen. Ein alternatives Verfahren, SHA-1, hat in der Zwischenzeit viel Boden gut gemacht, jedoch sind mittlerweile auch an SHA-1 Schwachstellen entdeckt worden. Die Nachfolge-Algoithmen SHA256 und SHA-512 haben bislang keine Schwachstellen aufgezeigt. Interessant vielleicht noch zu erwähnen, dass der SHA-Algorithmus von der NSA entwickelt wurde... Natürlich lassen sich Verschlüsselung und Signatur auch kombinieren um die Daten einerseits vor fremden Blicken zu schützen und die Integrität zu gewährleisten. Hierbei ist es jedoch nicht unerheblich ob zuerst verschlüsselt und dann signiert oder umgekehrt wird! Würde erst verschlüsselt und dann von den verschlüsselten Daten der Hashwert gebildet, so könnte Bob die Nachricht fälschen, indem er die ursprüngliche Signatur von Alice entfernt und dann selbst signiert und an Bob weiterleitet. Der Empfänger Bob kann nicht mehr erkennen, ob der Ciphertext von Alice verschlüsselt wurde, oder von Mallory. Je nachdem um welche Nachricht bei dem Ciphertext handelt, kann dies fatal sein... Aus diesem Grund muÿ immer zuerst signiert werden und der gesamte Datenblob danach verschlüsselt werden, denn dann ist eine bewusste Veränderung durch Mallory als Man in the middle ausgeschlossen, da dieser gar nicht mehr die Signatur von Alice durch seine eigene ersetzen kann, da nur der rechtmäÿige Empfänger der Daten, BoB, überhaupt in der Lage ist diese zu entschlüsseln und dann die Signatur zu prüfen. 6 JCE & Bouncy Castle Mittels der JCE, der Java Cryptographic Extension hat Sun bereits sehr früh (Java 1.2) den Grundstein zur Nutzung von kryptographischen Funktionen in seiner Klassenbibliothek gelegt. War die JCE anfangs noch als separater Download erhältlich, so ist sie seit Java 1.4 fester Bestandteil des J2SDK. Sun liefert mit der Installation des Java SDK also bereits alles mit, was benötigt wird um Applikationen zu entwickeln, die kryptographische Funktionen nutzen. Die JCE gliedert sich nahtlos in das JCF, das Java Component Framework ein. Neben der JCE gibt es noch andere Extensions die auch kryptographische Funktionen bereitstellen. Eine solche Erweiterung ist die Bouncy Castle API (im Folgenden einfach kurz BC tituliert) um die es im Rest dieser Ausarbeitung gehen soll. BC nimmt im JCF/JRE die Rolle eines Provider eine, dass heisst, es ist eines von mehreren Implementierungsbibliotheken aus denen der Anwender wählen kann. Diese Bibliotheken können sich z.B. in der Anzahl der unterstützen Verschlüsselungsalgorithmen unterscheiden, in der maximal möglichen Schlüssellänge usw. usf. Der Entwickler kann sich beim Nutzen der kryptographischen Funktionen entscheiden welchen Provider er verwenden möchte. Wird keine Vorselektion des Providers durch den Entwickler getroen, so kümmert sich die JCE um die Auswahl eines Providers. Der Charm für den Entwickler ist, dass er stets gegen die selbe API programmiert. Eine Applikation welche die BC API verwendet hat keine grundsätzlich anderen Methodenaufrufe als eine, die das JCE nativ verwendet! Lediglich der Initialisierungs-Aufruf des Providers unterscheidet sich. Quelle: http : //java.sun.com/developer/technicalArticles/Security/whitepaper/JSW hiteP aper.pdf Ein Mischen verschiedener Provider innerhalb einer Anwendung ist zwar möglich, es wird jedoch davon abgeraten. Die BC API bietet dem Anwendungsentwickler viel Komfort und eine Vielzahl von kryptographischen Funktionen. So sind z.B. in der BC API auch Algorithmen auf Basis elliptischer Kurven enthalten, um die es in diesem Text nicht gehen wird, welche aber das Potential haben, etablierte Verfahren wie RSA und DSA den Rang abzulaufen, da es mit Ihnen möglich ist, gleiche Sicherheit bei gesunkenem Hardwareaufwand und Schlüssellänge zu ereichen. 8 6.1 Download von Bouncy Castle Die Bouncy-Castle API kann im Internet von http : //www.bouncycastle.org/latestr eleases.html heruntergeladen werden. Wie für Java-Erweiterungen üblich erfolgt die Bereitstellung in Form eines JARArchives. Dieses JAR Archiv (bcprov-ext-jdk16-141.jar) muss in das lib ext Verzeichnis der JRE Installation kopiert werden, z.B. C : P rogramF iles Java jdk1.6.00 7 jre lib ext unter Windows. (Achtung: Die Extension muss in das Verzeichnis im jre Unterverzeichnis kopiert werden, nicht in das lib ext im JDK Hauptverzeichnis!) Nach dem die Datei in das Extension-Verzeichnis kopiert wurde, muss sie für das JDK noch aktivert werden. Hierzu muss die Datei java.security im gleichen Verzeichis bearbeitet werden. In dieser Datei sind u.a. sämtliche Provider aufgeführt. Die entsprechenden Zeilen beginnen mit security.provider.N=. An diese Liste muss die BC API manuell hinten wie aus der Abbildung ersichtlich angefügt werden und mit einer laufenden Nummer versehen werden. Achtung: Der BC Provider sollte immer als letzter Eintrag in die Liste eingefügt werden. 6.2 Aktivieren der unlimited strength Kryptographie Ende der 90er Jahre war es noch nicht ohne weiteres möglich starke Kryptographie für die breiten Massen zur Verfügung zu stellen. Die US-amerikanische Regierung (vor allem wohl unter Druck durch die NSA) wollte sicherstellen, dass verschlüsselte Kommunikation nur solange verschlüsselt blieb, solange sie nicht Staatsinteressen gefährdete und verbot kurzerhand alle Schlüssellängen >40 Bit. 40 bit lange Schlüssel waren selbst für versierte Angreifer keine unüberwindlichen Hürden und für die von Geheimnissen umwitterte NSA mit Sicherheit gar keine mehr. Mit der Rechenkraft heutiger Heimcomputer kann jedermann 40 bit lange Schlüssel in Kürze knacken, so dass diese auch für nicht so wichtige Daten nicht mehr verwendet werden sollten. 40 Bit Schlüssel sind kaum besser als gar keine Verschlüsselung. Der Standard ist heute eine Verschlüsselung mit 128 Bit. Da es aber nach wie vor Länder gibt, die den Einsatz starker Kryptographie nicht gestatten (Referen- 9 zen: France? China?) bzw. andererseits Kryptographie unter das Waen-Exportgesetz fällt, ist es nicht möglich ein JDK auszuliefern, welches von vornherein diese langen Schlüssellängen unterstützt. In dem Originalauslieferungszustand des SDKs bzw. JREs sind daher die maximal möglichen Schlüssellängen sowie die nutzbaren Algorithmen eingeschränkt. Welche Schlüssellängen mit einem JDK möglich sein, wird über eine sogenannte Policy-Datei festgelegt. Um starke Kryptographie einzusetzen, bietet Sun den Download einer weitern Policydatei an, die keinerlei Einschränkungen mehr enthält, allerdings muss sich der Anwender diese explizit besorgen. Wird diese Policy-Datei java.security in die Verzeischnisstruktur lib/security des JRE eingespielt, so ist ohne weitere Änderungen der Einsatz groÿer Schlüssellängen sofort möglich. Wird in einer Applikation versucht, starke Kryptographie ohne Vorhandensein der unlimited policy datei zu verwenden so ist die Folge ein Laufzeitfehler/Exception. Die Policy-Datei (ozielle Bezeichnung Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy) kann von der Sun Webseite bezogen werden. Der Download bendet sich ganz unten auf der Downloadseite des J2SDK: http://java.sun.com/javase/downloads/?intcmp=1281 6.3 Test der Installation Um die Installation der Bouncy Castle API und der unlimited strength Policy zu testen, kann folgendes kleines Java-Programm verwendet werden: Listing 1: SimplePolicyTest.java import j a v a x . c r y p t o . ∗ ; import j a v a x . c r y p t o . s p e c . ∗ ; public c l a s s S i m p l e P o l i c y T e s t { public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { byte [ ] data = " H e l l o World ! " . g e t B y t e s ( ) ; // c r e a t e a 64 b i t s e c r e t key from raw b y t e s SecretKey key64 = new SecretKeySpec ( new byte [ ] { 0 x00 , 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x05 , 0 x06 , 0 x07 } , " Blowfish " ) ; // c r e a t e a c i p h e r and a t t e m p t t o e n c r y p t t h e d a t a b l o c k w i t h our key Cipher c = Cipher . g e t I n s t a n c e ( " B l o w f i s h /ECB/PKCS7Padding" , "BC" ) ; 10 Abbildung 4: Der Downloadlink zum unlimited strength"Policy le c . i n i t ( Cipher .ENCRYPT_MODE, key64 ) ; byte [ ] out = c . d o F i n a l ( data ) ; out = new byte [ ] { 0 x00 } ; System . out . p r i n t l n ( " 64 b i t t e s t : p a s s e d " ) ; // c r e a t e a 192 b i t s e c r e t key from raw b y t e s SecretKey key192 = new SecretKeySpec ( new byte [ ] { 0 x00 , 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x05 , 0 x06 , 0 x07 , 0 x08 , 0 x09 , 0 x0A , 0 x0B , 0 x0C , 0 x0D , 0 0 x10 , 0 x11 , 0 x12 , 0 x13 , 0 x14 , 0 x15 , 0 " Blowfish " ) ; // now t r y e n c r y p t i n g w i t h t h e l a r g e r key c . i n i t ( Cipher .ENCRYPT_MODE, key192 ) ; out = c . d o F i n a l ( data ) ; c . i n i t ( Cipher .DECRYPT_MODE, key192 ) ; out = c . d o F i n a l ( out ) ; } } System . out . p r i n t l n ( " 192 b i t t e s t : p a s s e d " ) ; System . out . p r i n t l n ( " T e s t s completed " ) ; Ist das JDK korrekt konguriert wird die folgende Meldung ausgegeben: 64 bit test: passed 192 bit test: passed Tests completed Ist etwas nicht in Ordnung kommt es zu einer Exception. In diesem Fall sollte die Installation erneut überprüft werden. Für alle weiteren Beispiele dieser Ausarbeitung wird davon ausgegangen dass die erweiterte PolicyDatei verwendet wird und die BC API aktiviert wurde. In der weiteren Beschreibung dieses Dokumentes orientiere ich mich an dem hervorragenden Buch Cryptography with Java von David Hook. 11 6.4 Aufbau der JCE Die JCE beinhaltet ein wahres Füllhorn an kryptographischen Funktionen. Von Hashfunktionen über Stream und Block-Chiren, asymmetrischer Kryptographie und Signaturverfahren ist alles enthalten was das Kryptologen-Herz begehrt. Ist der BC Provider wie oben beschrieben aktiviert stehen die entsprechenden Funktionen der BC API zur Verfügung Die Klassen der BC API sind hierbei java-typisch in packages sortiert. Folgende (grobe) package struktur ist hierbei gewählt worden: org.bouncycastle.asn1.* org.bouncycastle.crypto.* org.bouncycastle.util.* org.bouncycastle.x509.* Daneben gibt es noch weitere Packages Innerhalb des Packages asn1 stehen Klassen für die Verarbeitung von ASN.1 Objekten zur Verfügung. Die crypto packages enthalten Basisimplementierungen für die Verschlüsselung, util enthält Hilfsklassen, und x509 Klassen rund um X509.x Zertikate. Wie für die JCE üblich werden nie direkt Objekte aus den Klassen des BC API erzeugt. Stattdessen wird das Factory-Pattern verwendet um Instanzen der jeweiligen Klassen zu erhalten. 6.5 Die Cipher-Klasse Mit Hilfe von Methoden der Cipher-Klasse können Daten verschlüsselt werden. Egal welches Verfahren und welche Schlüssellänge verwendet werden soll, es werden stets die selben 4 Methoden verwendet: • Cipher.getInstance(String algo, String provider) Über diesen Methodenaufruf wird der Verschlüsselungsalgorithmus, der Mode, das Padding und der Provider ausgewählt algo ist hierbei ein String wie z.B. DES/CBC/PKCS5Padding welcher in diesem Fall ein Objekt zurückliefert mit dem Daten via DES im CBC Mode verschlüsselt werden können. Das Padding wird gemäÿ PKCS5 durchgeführt. provider kann als String übergeben werden. Für unsere Beispiele ist dies stets BC um die BC API zu nutzen. Es gibt weitere Überladungen dieser Klasse. • Cipher.init(int mode, Key key) Mit Hilfe dieser Methode wird der Mode (ENCRYPT_MODE, DECRYPT_MODE) gesetzt und der Key der für die Verschlüsselung verwendet werden soll deniert. Die Init-Methode muss stets zuvor aufgerufen worden sein, bevor eine update() oder doFinal()-Operation ausgeführt wird. Es gibt weitere Überladungen dieser Klasse. • Cipher.update(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) Cipher.doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) Hiermit die Verschlüsselung des Plaintextes input ab dem Oset inputOset für inputLen Zeichen durchgeführt und in den Ausgabe-Puer output ab Index outputOset geschrieben. Die doFinal()-Methode schliesst den Vorgang ab. Es ist auch möglich den gesamten Plaintext mittels eines Aufrufes von doFinal() zu verschlüsseln. Ob segmentweise (mittels update()) oder alles auf einmal (mittels doFinal()) verschlüsselt wird wird durch den konkreten Problemfall bestimmt. Es gibt diverse Überladungen dieser Klassen. 6.6 Die SecretKeySpec-Klasse Das Objekt SecretKeySpec repräsentiert einen Verschlüsselungsschlüssel. Verschiedene Crypto-Algorithmen, wie z.B. AES, nutzen nicht direkt einen Schlüssel, sondern leiten aus diesem Schlüssel die tatsächlichen Schlüssel ab. Für AES werden z.B. 10 verschiedene Schlüssel genutzt. 12 • SecretKeySpec(byte[] key, String algo) Der Parameter key gibt hierbei den Schlüssel an, algo den zu verwendeten Algorithmus. Dieses Objekt ist nicht dafür gedacht, das verwendete Passwort für eine Verschlüsselung als byte[] entgegenzunehmen, hierfür die die Klasse PBEKeySpec() vorgesehen. Wie groÿ das übergebene byte[] sein muss, wird durch die Wahl des Verschlüsselungs-Algorithmus bestimmt. Im Falle von DES muss es z.B. 8 Byte lang sein. Eine Überprüfung ndet nicht statt! Es versteht sich von selbst, dass der angegebene algo im Konstruktor schluÿendlich zum Algorithmus des Cipher-Objektes passen muss, damit die beiden Objekte miteinander harmonieren. Um beispielsweise die für AES notwendigen Keys aus dem Passwort Hello World! abzuleiten kann ein SecretKeySpec der folgenden Form erstellt werden. SecretKeySpec sks = new SecretKeySpec("Hello world!".toByteArray(), "AES") • getEncoded() gibt das Schlüsselmaterial im Rohformat zurück. 6.7 Die IvParameterSpec-Klasse Die Klasse IvParameterSpec repräsentiert einen IV-Vektor (IV). Wozu ein IV notwendig ist, ist im Abschnitt über Block-Chiren beschrieben. • IVParameterSpec(byte[] iv) erzeugt ein IvParameterSpec-Objekt. • byte[] getIv() gibt den IV zurück. 6.8 Die PBEKeySpec-Klasse Die Klasse PBEKeySpec kann verwendet werden um einen Schlüssel aus einem Passwort abzuleiten. Gemeinhin wird nie das Passwort selbst für die Verschlüsselung verwendet, sondern immer der eigentliche Schlüssel nach einem festen Algorithmus daraus abgeleitet. Weit verbreitete Algorithmen hierfür sind jene welche in den Standard PKCS#5 und PKCS#12 deniert sind. Die Klasse schützt (natürlich) nicht davor, dass das Passwort trivial ist! Der beste AES-256 nutzt nichts wenn als Passwort lediglich hallo verwendet wird. Die nutzende Applikation sollte einen Trivialitätscheck durchführen! • PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength) erzeugt ein PBEKeySpec-Objekt. Das übergebene Passwort wird hierbei als char[] übergeben und nicht als String, damit es möglich ist, dass Passwort im Speicher wieder explizit zu löschen. Damit das gleiche Passwort nicht stets zum gleichen Schlüssel konvertiert wird, wird ein sogenanntes Salt verwendet. Dies ist ein paar Zufallsbytes (z.B. Uhrzeit) welche an das Passwort drangehängt werden und somit jedes Passwort individualisieren. Dies macht es möglich, dass gleiche Passwort für unterschiedliche Zwecke zu verwenden und dennoch jedesmal einen anderen Schlüssel zu erhalten. Ein Angreifer kann dann nicht erkennen ob es sich stets um das gleiche Ausgangspasswort handelt oder um unterschiedliche Passwörter die er knacken muss. Das Salt ist normalerweise so groÿ wie die Hash-Länge des für die Schlüsselaufbereitung verwendeten Hash-Algorithmus. Der Algorithmus zur Schlüsselaufbereitung wird iterationCount oft durchlaufen. Hierdurch erhöht sich der Aufwand zusätzlich für einen Angreifer. Würde kein Salt verwendet und ein Passwort aus einem Wörterbuch verwendet welches 100 verschiedene Wörter enthält, so muss der Angreifer nur 100 Varianten durchprobieren. Wird der iterationCount jedoch hoch gesetzt (z.B. auf 1000 oder 4000) so wird jedes Passwort zunächst 4000-mal von der Passwort-Aufbereitungsroutine durchlaufen. Der Aufwand wächst linear. keylength letztlich bestimmt wie lang (in Bit) das aufbereitete Passwort werden soll. • getPassword() gibt das aufbereitete Passwort zurück. 13 Folgendes Code-Beispiel verschlüsselt den Text Hello World mit dem Passwort ThePassword1! mit dem AES-Algorithmus im CBC Verfahren: Listing 2: SimplePolicyTest.java s t r i n g i = " H e l l o World ! " ; byte [ ] i n p u t = i . toByteArray ( ) ; byte [ ] keyBytes = " ThePassword1 ! " . toByteArray ( ) ; SecretKeySpec key = new SecretKeySpec ( keyBytes , "AES" ) ; IvParameterSpec i v S p e c = new IvParameterSpec ( new byte [ 8 ] ) ; Cipher c i p h e r = Cipher . g e t I n s t a n c e ( "AES/CBC/PKCS7Padding" , "BC" ) ; c i p h e r . i n i t ( Cipher .ENCRYPT_MODE, key , i v S p e c ) ; byte [ ] c i p h e r T e x t = c i p h e r . d o F i n a l ( i n p u t ) ; Die Eingabeparameter für die Verschlüsselung müssen in Form von byte[] vorliegen. An Eingabeparamtern haben wir: input - den eigentlichen Text der verschlüsselt werden soll, keyBytes - das Passwort mit dem ver- und entschlüsselt werden kann, ivBytes, den Initialisierungsvektor. Damit das Passwort für BC nutzbar ist, muss daraus ein SecretKeySpec Objekt erzeugt werden. Wir wollen den AES Algorithmus verwenden und geben dies daher in der Konsturktion des Objektes an. SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); Analog gehen wir für die Erzeung des IV vor, nur dass dieser keinen Algorithmus benötigt: IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); In der nächsten Zeile holen wir ein Cipher-Objekt mit welchem im AES, CTR, NoPadding verschlüsselt werden kann. Das Objekt soll der Provider BC zur Verfügung stellen. Würde man BC an dieser Stelle weglassen, so würde der native Sun Cipher verwendet werden, der natürlich genauso gut verwendet werden könnte. Allerdings sollte man sich innerhalb eines Programms auf einen Crpytographic Service Provider (CSP) festlegen, da nicht alle CSPs untereinander voll kompatibel sind. Wichtigster Schritt vor dem Beginn der Verschlüsselung ist die Initialisierung des Cipher-Objektes durch den Aufruf der init-Methode cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); Diesem Aufruf geben wir den Mode mit (ENCRYPT_MODE - wir wollen verschlüsseln), den Key sowie den IV). Die eigentliche Verschlüsselung des Textes erfolgt nun durch den Aufruf cipher.doFinal(input), welcher den byte[] Input nimmt, diesen mit dem konguriertem Algorithmus verschlüsselt und ein byte[] zurückgibt. Die Entschlüsselung des Cipher-Textes erfolgt völlig analog wie das folgende Beispiel zeigt. byte[] input = cipherText; byte[] keyBytes = "ThePassword1!".toByteArray(); byte[] ivBytes = new byte[] { 0x00 }; SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding", "BC"); cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); byte[] plainText = cipher.doFinal(input); Der wesentliche Unterschied ist hier die Verwendung der Konstante Cipher.DECRYPT_MODE im Aufruf von cipher.init() 14 7 Asymmetrische Verschlüsselung von Daten 8 Hashfunktionen und Signaturen 9 Keystores und Zertikate 10 SSL und TLS 11 Standards und Schnittstellen PKCS 12 Ausblick 12.1 Starke Kryptographie, Smartcards, Token, HSMs Alle die in diesem Artikel vorgestellten Verfahren verwenden ein secret zur Verschlüsselung der Daten, sei es ein Passwort oder ein private Key. Letztendlich hängt die Gesamtsicherheit der Verschlüsselung zu einem nicht unwesentlichen Teil von der Geheimhaltung eben jenes Schlüssels ab. Liegt die Schlüsseldatei lediglich auf der Festplatte des Anwenders so kann diese durch Schadsoftware wie Trojaner oder Viren manipuliert werden. Im einfachsten Fall werden die Schlüssel einfach gelöscht, im schlimmsten Fall wírd eine Kopie der Schlüssel gezogen und ein unerkannter Dritter in die Lage versetzt die vertrauliche Kommunikation mitzulesen. Dies ist inbesondere bei nanziellen transaktionen wie z.B. beim Online-Banking ein hohes risiko. NNicht zuletzzt aus Versicherungstechnischen und rechtlichen Gründen gehen daher immer mehr Banken dazu über, Ihren Kunden Smartcards oder Token auszustellen und keine PIN/TAN Listen mehr zu verwenden, was letztendlich nicht anderes als Passwort-Listen sind. Eine Smartcard oder ein Token sind nah verwandt. Während eine Smartcard in der Regel wie eine EC-Karte mit Geld-Chip aussieht und ein separates Lesegerät (den Smartcard reader) benötigt, ist ein Token eine all in one Lösung die Smartcard und Leser in einem Gerät kombiniert und in der Regel über einen USB-Anschluÿ verfügt. Beiden Verfahren ist gemein, dass sie eine sogenannte 2-Faktor-Authentizierung unterstützen, indem es nun nich tmehr darum gibt something you know (das Passwort) sondern nun 2 Faktoren notwendig sind um die Daten zu verschlüsseln: Something you know (PIN) und Something you have (das token/Smartcard). Eine nochmals erhöhte Sicherheit kann durch eine 3-Faktor-Authentizierung erreicht werden: Something you own, Something you know, Something you are. Something you are sind hierbei biometrische Merkmale wir ein Fingerabdruck, ein Retina-Scan oder ein digitaler Voiceprint. Groÿe Firmen die sich eine eigene PKI leisten, gehen dazu über Mitarbeiterausweise mit digitalen Zertikaten für die Signatur und Verschlüsselung auszustatten um jedem Mitarbeitern das Rüstzeug für die sichere Kommunikation zur Verfügung zu stellen. Häug sind diese Ausweise dann auch noch mit berührungslosen RFID Transmittern ausgestattet um z.B. den Zugang zu Räumen zu reglmentieren. Für High-End-Security Anforderungen, besonderns im Banken und CA Umfeld kommen sogenannte HSMs, Hardware Security Modules, zum Einsatz. Hierbei handelt es sich oftmals um groÿe Smartcards in der Form von PCI Steckboards oder kompletten 19Äppliances welche zusätzlich besonders gegen physiaklische Angrie geschützt sind. Ein HSM besitzt normalerweise einen eigenen Kryptoprozessor welcher in der Lage ist sehr schnell kryptographische Operationen durchzuführen, einen echten Zufallszahlengenerator, einen sicheren Hochgeschwindigkeitsspeicher welcher im Falle eines Angris innerhlab von Nanosekunden das Schlüsselmaterial aus dem Speicher löscht und somit für einen ANgreifer wertlos macht sowie EInbruchssensoren. Erkennen diese Sensoren einen Angri, etwa eine stark erhöhte Temperatur im Falle des Versuchs ein HSM aufzuschweissen oder starke Spannung, so sorgen die Sensoren für die schnelle und restlose Vernichtung des Schlüsselmaterials des Schlüsselmaterials im Speicher der HSM. Für eine Dieb ist die HSM dadurch nutzlos geworden. Einer Smartcard ist eine HSM in Sachen performance deutlich überlegen. Wo es bei einer Smartcard auf jedes Quentchen an Taktersparnis und Speichernutzung ankommt, kann man bei einer HSM normalerweise aus den Vollen schöpfen. Erkaufen tut man sich diesen Luxus mit einem zu einer Smartcard vielfach höheren Preis, welcher nicht selten bei einigen Zehntausend EUR startet... 15 Abbildungsverzeichnis Tabellenverzeichnis Literatur 16