Base64-Kodierung (unter Java 8)

Für die Übertragung von Binärdaten hat sich im Internet die Base64-Kodierung durchgesetzt, die zum Beispiel bei E-Mail-Anhängen und SOAP-Nachrichten zu finden ist. Auch bei der HTTP-Authentifizierung Basic Authentication kommt Base64 zum Tragen, denn die Konkatenation von Benutzername + „:“ + Passwort wird über Base64 codiert und so zum Server gesendet – der Sicherheitsgewinn ist natürlich null.

Die Base64-Kodierung wird im RFC 4648[1] beschriebene. Drei Bytes (24 Bit) werden in vier Base64-kodierte Zeichen (vier Zeichen mit jeweils sechs repräsentativen Bits) umgesetzt. Die Konsequenz dieser Umformung ist, dass Binärdaten rund 33  % größer werden. Die Base64-Zeichen bestehen aus den Buchstaben des lateinischen Alphabets, den Ziffern 0 bis 9 sowie (im Normalfall) »+«, »/« und »=«.

Das JDK liefert seit Java 8 direkte Unterstützung für diese Base64-Umsetzung mit der Klasse java.util.BASE64 aus. Zwei inneren Klassen Base64.Decoder bzw. Base64.Encoder kümmern sich um die Umwandlung. Zur Erzeugung der Exemplare gibt es statische Methoden in BASE64, und zwar nicht nur zwei, sieben. Der Grund ist, dass es neben der Standard-Konvertierung „Base“ noch MIME und URL/Dateiname-sicher gibt:

· getEncoder() und getDecoder() liefern Exemplare vom Typ Base64.Encoder und Base64.Decoder bzw. für den normalen Basic-Typ.

· getEncoder(int lineLength, byte[] lineSeparator), getMimeEncoder() und getMimeDecoder() liefern Encoder/Decoder für MIME-Nachrichten, bei der Zeilen mit einem „\r“ getrennt sind.

· getUrlEncoder() und getUrlDecoder() nutzt zur Kodierung nur Zeichen, die für URL und Dateinamen gültig sind, und ersetzt „+“ durch „-“ und „/“ durch „_“.

Beispiel

Das folgende Beispiel erzeugt zuerst ein Byte-Feld mit Zufallszahlen. Die Base64-Klasse kodiert das Byte-Feld in einen String, der auf dem Bildschirm ausgegeben wird. Nachdem der String wieder zurückkodiert wurde, werden die Byte-Felder verglichen und liefern natürlich true:

byte[] bytes1 = SecureRandom.getSeed( 20 );

// byte[] -> String

String s = Base64.getEncoder().encodeToString( bytes1 );

System.out.println( s ); // z.B. TVST9v+JMk/vVUOSENmIcriXFLo=

// String -> byte[]

byte[] bytes2 = Base64.getDecoder().decode( s );

System.out.println( Arrays.equals(bytes1, bytes2) ); // true

Wer nicht mit Java 8 arbeiten kann, aber mit älteren Versionen vom Oracle JDK, der kann BASE64Encoder/BASE64Decoder aus dem nicht-öffentlichen Paket sun.misc nutzen.[2] Wem das nicht ganz geheuer ist, der kann javax.mail.internet.MimeUtility von der JavaMail-API nutzen[3] oder unter http://jakarta.apache.org/commons/codec/ die Commons Codec-Bibliothek beziehen.


[1] http://tools.ietf.org/html/rfc4648

[2] Siehe dazu http://java.sun.com/products/jdk/faq/faq-sun-packages.html. Bisher existieren sie aber seit über zehn Jahren, und wer Oracles Philosophie kennt, der weiß, dass die Abwärtskompatibilität oberste Priorität hat.

[3] http://www.rgagnon.com/javadetails/java-0598.html gibt ein Beispiel. Die JavaMail-API ist Teil von Java EE 5 und muss sonst für das Java SE als Bibliothek hinzugenommen werden.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.