Open Source im professionellen Einsatz
Linux-Magazin 01/2012

Programmieren mit der Java-SE-Security-Bibliothek

Schloss und Siegel

Die Vorbeugung gegen Datendiebstahl und illegale Zugriffe spielt bei der Anwendungsentwicklung eine immer größere Rolle. Der Java-Programmierer findet in der Java-SE-Security-Bibliothek, was er braucht, um Daten zu ver- und entschlüsseln sowie Prüfsummen und Signaturen einzusetzen.

697

Sicherheitsaspekte werden bei der Produktion von Software immer wichtiger. Inzwischen stehen sie gleichberechtigt neben den funktionalen Anforderungen und bestimmen nicht selten die Software-Architektur. Sicherheitsfragen umfassen ein weites Feld, sei es der unberechtigte Zugriff Dritter auf Daten, unbemerkte Änderungen daran oder das Ausführen ungewollter Fremdprogramme.

Um dies zu verhindern, bietet Java in der Security-Bibliothek eine Reihe von Funktionalitäten an. Das reicht von der klassischen Verschlüsselung über digitale Signaturen bis hin zu eingeschränkten Rechten für Java-Programme selbst. Dies ist Teil der normalen Java-Distributionen (Open JDK und Oracle-Java) und in den Paketen und »javax.security« und »javax.crypto« zu finden.

Den Aufbau der Pakete gibt die Java Cryptography Architecture (JCA, [1]) vor. Den Kern bildet eine Handvoll Klassen für Sicherheitsaufgaben wie etwa Verschlüsselung oder Signatur. Die Klasseninstanzen erzeugt der Programmierer nicht wie üblich mit »new« , sondern er ruft sie bei einer Factory-Methode für den gewünschten Algorithmus ab. Dadurch ist pro Aufgabe unabhängig von der Anzahl verfügbarer Algorithmen nur noch eine Klasse erforderlich.

Krypto-Alternative

Diese Flexibilität reicht über die Algorithmen hinaus bis hin zur verwendeten Implementierung. So steht als Alternative zu Oracles Umsetzung unter anderem die umfangreichere und MIT-lizenzierte Ausgabe der Programmierergruppe Legion of the Bouncy Castle [2] zur Verfügung. Der Preis für diese Flexibilität liegt auf der Hand: Anfragen mit falschen Namen bestraft Java mit der Ausnahme »NoSuchAlgorithmException« . Abbildung 1 zeigt die in der JDK-Version 7 verfügbaren Algorithmen, das zugehörige Programm findet sich in den Beispiel-Quelltexten zu diesem Artikel [3].

Es liegt nahe, sensible Daten durch Verschlüsseln zu schützen. Symmetrische Verfahren wie der Advanced-Encryption-Algorithmus (AES) verwenden dabei zweimal den gleichen Schlüssel: Um die Originaldaten in eine unlesbare Form zu verwandeln und um sie wieder zu entschlüsseln (Abbildung 2).

Geheim!

Den typischen Aufbau für Ver- und Entschlüsselprogramme in Java zeigt Listing 1. Es führt die Operationen über ein »Cipher« -Objekt durch, das es für den gewünschten Algorithmus über die »getInstance()« -Methode erzeugt (Zeile 1). Das Beispiel nutzt AES mit einer Schlüssellänge von 128 Bit. Passend zu »Cipher« erzeugt der »Keygenerator« einen Schlüssel, entweder – wie im Listing – als zufälligen Einmalschlüssel oder basierend auf einem Passwort. Vor der Verwendung muss der Programmierer das Cipher-Objekt mit dem Schlüssel für die gewünschte Richtung initialisieren (Zeile 8).

Listing 1

Symmetrische Verschlüsselung mit AES

01 Cipher cipher = Cipher.getInstance("AES-128");
02
03 KeyGenerator kgen = KeyGenerator.getInstance("AES-128");
04 kgen.init(128);
05
06 SecretKey skey = kgen.generateKey();
07
08 cipher.init(Cipher.ENCRYPT_MODE, skey);
09
10 String klartext = "Die Botschaft";
11 System.out.println("Klartext " + klartext );
12
13 byte[] zuVerschluesseln =klartext.getBytes();
14 // Die Verschlüesselung
15 byte[] verschluesselt = cipher.doFinal( zuVerschluesseln );
16 // Kodieren für einen sicheren Texttransport
17 String verschluesseltB64 = new String( Base64.encodeBase64( verschluesselt ) );
18 System.out.println( "Verschlüsselt       " + verschluesseltB64 );
19
20 // Dekodieren
21 byte[] verschluesselt2 = Base64.decodeBase64( verschluesseltB64.getBytes() );
22
23 // Die Entschlüsselung mit dem gleichen Schlüssel
24 cipher.init(Cipher.DECRYPT_MODE, skey);
25
26 byte[] entschluesselt = cipher.doFinal(verschluesselt2);
27 System.out.println("Entschlüsselt " + new String(entschluesselt) );

Alle kryptographischen Methoden arbeiten auf der Basis von Byte-Arrays, Texte muss ein Programm daher wie in Zeile 13 konvertieren. Zur eigentlichen Verschlüsselung nutzt der Java-Entwickler bei kleinen Mengen direkt die »doFinal()« -Methode der Cipher-Klasse (Zeile 15). Für größere Mengen bietet sich das Verschlüsseln mit »CipherOutputStream« beziehungsweise »CipherInputStream« an. Der durchgeleitete Datenstrom wird dann im Stream mit dem »Cipher« -Objekt ver- oder entschlüsselt.

Möchte der Entwickler die verschlüsselten Daten wieder als Text übertragen, sind Byte-Arrays sehr unhandlich. Hier hat sich das Kodieren als Base64 bewährt. Die Bytes (-128 bis 127) werden dabei auf die in allen Systemen übertragbaren Buchstaben des englischen Alphabets abgebildet (Zeile 17). Leider enthält Java keinen Base64-Encoder im öffentlichen API, das Beispiel verwendet deshalb die Base64-Klasse aus der Apache-Commons-Codec-Bibliothek [4].

Die Entschlüsselung durchläuft die Schritte in umgekehrter Reihenfolge: Das Programm dekodiert zunächst Base64 in ein Byte-Array und entschlüsselt dieses per Cipher-Objekt. Das Cipher-Objekt muss der Java-Entwickler für beide Richtungen mit den gleichen Parametern und Schlüsseln erstellen, ansonsten schlägt die Entschlüsselung fehl.

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Guadec 2010: Gnome-Keyring als gemeinsamer Keystore

    Der Gnome-Entwickler Stef Walter hat sich in seinem Guadec-Vortrag damit beschäftigt, Kryptografie-Komponenten benutzerfreundlicher zu machen. Als gemeinsamen Keystore für Anwendungen in Gnome 3.0 schlägt er Gnome-Keyring vor.

  • HTC Android-Smartphones: Zugriff auf WLAN-Passwörter
  • Der mit dem Kater tanzt

    Sowohl der Webserver Apache als auch der Servlet-Container Tomcat werden von der Apache Software Foundation gepflegt. Ein perfektes Zusammenspiel scheint daher selbstverständlich. Doch die Realität sieht anders aus. Dieser Coffee-Shop zeigt Ansätze für eine Lösung.

  • XML-Futter für Java-Objekte mit Digester 2.0

    Die neue Version besitzt weniger Abhängigkeiten und kann XML-Code validieren. Digester findet Anwendung, wenn Programmierer Daten aus XML-Dateien in Java-Objekte umwandeln wollen.

  • Geld-Transport

    Das Home Banking Computer Interface (HBCI) ist für Bankgeschäfte im Internet die ideale Basis: Sicher, standardisiert und multibankfähig deckt es alle wichtigen Geschäftsvorfälle ab. Dieser Beitrag erklärt Aufbau und Abläufe sowie die Sicherheitsmechanismen.

comments powered by Disqus

Ausgabe 07/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.