Passwörter durch Hashfunktionen absichern

In der vergangenen Woche bin ich über einen interessanten Artikel gestolpert, der sich mit dem Absichern von Passwörter mit Hashfunktionen beschäftigt. Neu ist die Thematik nicht, sollten die dort beschriebenen Vorgehensweisen zur Grundausstattung einer jeden Anwendung gehören, die mit Authentifizierungs-Mechanismen arbeitet. Interessant an dem Artikel ist aber vor allem, dass durch den rasanten Zuwachs an Rechenleistung, insbesondere durch den Einsatz der GPU, sich Passwörter wesentlich leichter “errechnen” lassen. Ausgehend natürlich von einem Szenario, in der die Datenbank einer Anwendung kompromittiert wurde. Direkte Angriffe auf Login-Seiten sind eine ganz andere Geschichte.

Folgt man den Empfehlungen im o.g. Artikel, so lassen sich folgende Tipps ableiten:

  • Passwörter sollten mind. 12 Zeichen oder mehr lang sein und Sonderzeichen sowie Groß- und Kleinschreibung enthalten (Empfehlung: Passphrasen)
  • SHA256 (oder größer) ist MD5 vorzuziehen (Siehe auch).
  • Es sollte nicht einen allgemeinen Salt geben, sondern jeder Benutzer sollte einen eigenen Salt erhalten (Siehe auch). Der Salt sollte nicht aus Benutzerinformationen zusammengesetzt, sondern Zufällig erstellt werden.
  • Durch Key Stretching sollte die benötigte Rechenzeit des Angreifers zusätzlich erhöht werden.
  • Sofern möglich, sollte man auf alternative Hashing-Algorithmen wie bcrypt, PBKDF2 oder scrypt zurückgreifen.

Neues in Java 7 – Diamond Operator

Dieser Beitrag soll der Erste einer ganzen Reihe von Beiträgen sein, die sich mit den Neuheiten in Java 7 beschäftigen. Heutiges Thema: der Diamond Operator.

Seit Java 5 ist es möglich über Generics Datentypen zu definieren. Eine typische Definition sieht in etwa so aus:

Map<<String, List<String>> m = new HashMap<String, List<String>> ();

Das “Unschöne” an einer solchen Deklaration ist, dass man auf beiden Seiten die Typdefinition vornehmen muss, gleichwohl die rechte Seite eigentlich der linken entspricht. Mit Java 7 leitet der Compiler nun einfach die rechten Seite von der linken ab, so dass man stattdessen folgendes schreiben darf:

Map<<String, List<String>> m = new HashMap<> ();

Play Framework 2.0


Nach vier Release Canidates wurde am 18. März die Version 2.0 des Play Frameworks in Verbindung mit dem Typesafe Stack 2.0 veröffentlicht. Der Sprung von Version 1.x auf 2.x ist groß, größer als ich erwartet hatte. Viele Entwickler die (wie ich) den Einstieg in Play mit der Version 1.x begonnen haben werden sich an einigen Stellen fragen, ob sie noch das gleiche Framework benutzen. Play2 wurde von Grund auf neu implementiert. Eine der wichtigsten Änderungen ist deshalb, dass das komplette Framework nicht mehr auf Java, sondern auf Scala basiert. Gleichzeitig lassen sich nun entweder Java- oder Scala-basierte Applikationen erstellen. Letzteres war zwar bereits seit Version 1.1 möglich, allerdings musste man dafür ein zusätzliches Modul einbinden.

Der für mich größte Wechsel ist im Bereich der Persistenz vollzogen worden. Hatte ich mich gerade an JPA in Play1 gewöhnt, so wird in Play2 auf Ebean als OR-Mapper gesetzt. Man kann zwar weiterhin JPA benutzen, allerdings muss dies vollständig manuell konfiguriert werden (XML lässt grüßen; womit man eigentlich wieder beim J2EE-Stack ist). Ich habe mich noch zu wenig mit Ebean beschäftigt, aber die Annotation scheinen nahezu 1:1 kompatibel mit denen bei JPA zu sein. Einzig allein die Queries erscheinen mir zwar flexibler, aber nicht ganz so selbsterklärend wie bei JPA.

Ebenfalls eine große Änderung gab es im Bereich der Template-Engine. In Play1 wurde auf Groovy-Templates gesetzt. Dies wurden vollständig (primär aus Performancegründen) durch eine Scala-Template-Engine ersetzt. Glaubt man den Entwickler, benötigt man nur wenig Zeit um sich die Groovy-Template-Engine von Play1 anzusehen (kann ich bestätigen). Genauso wenig Zeit benötigt man um sich die Scala-Template-Engine anzusehen. In einem halben Tag sollte man also genauso gut mit Scala-Templates arbeiten können, wie zuvor mit den Groovy-Templates. Wer sich nicht von seinen Groovy-Templates trennen kann (oder möchte), dem empfehle ich das Modul Faster-Groovy-Templates. Diese Erweiterung beschleunigt nicht nur das Rendern der Templates in Play1, sondern ermöglicht auch die Verwendung der Groovy-Templates in Play2.

Es gibt noch eine ganze Reihe weiterer Änderungen in Play2. Hierzu empfehle ich die Präsentation von Peter Hilten auf der Jfokus 2012.

Auch wenn die Entwickler nach wie vor betonen, dass Java weiter als nativer Bestandteil im Framework erhalten bleiben wird, sagt mir mein Bauchgefühl das der Java-Zweig früher oder später abgeschnitten wird. Der Sog richtig Scala, insbesondere durch die Integration in Typesafe, ist hier IMHO sehr hoch. Ich hoffe natürlich, dass mein Bauchgefühl mich hier täuscht und freue mich auf erste Play2 Applikationen. Und für mich bleibt Play eines der effizientesten und leistungsstärksten Web-Frameworks.

Bild: www.playframework.org

HTTP Response komprimieren

In den Code Snippets auf der Play Framework Webseite habe ich eine einfache Lösung gefunden um eine HTTP-Response bei der Auslieferung zu komprimieren. Dafür wird lediglich eine zusätzliche Controller-Klasse benötigt (hier Compress.class).

package controllers;

import play.*;
import play.mvc.*;

import java.io.*;
import java.util.*;
import java.util.zip.GZIPOutputStream;

public class Compress extends Controller {
    @Finally
    public static void compress() throws IOException {
        String text = response.out.toString();

        final ByteArrayOutputStream gzip = gzip(text);
        response.setHeader(&quot;Content-Encoding&quot;, &quot;gzip&quot;);
        response.setHeader(&quot;Content-Length&quot;, gzip.size() + &quot;&quot;);
        response.out = gzip;
    }

    public static ByteArrayOutputStream gzip(final String input) throws IOException {
        final InputStream inputStream = new ByteArrayInputStream(input.getBytes());
        final ByteArrayOutputStream stringOutputStream = new ByteArrayOutputStream((int) (input.length() * 0.75));
        final OutputStream gzipOutputStream = new GZIPOutputStream(stringOutputStream);

        final byte[] buf = new byte[5000];
        int len;
        while ((len = inputStream.read(buf)) &gt; 0) {
            gzipOutputStream.write(buf, 0, len);
        }

        inputStream.close();
        gzipOutputStream.close();

        return stringOutputStream;
    }
}

Jeder Controller-Klasse die komprimiert ausgeliefert werden soll wir anschließend mit der Annotation

@With

versehen.

@With(Compress.class)
public class Application extends Controller {
   public static void index() {
       render();
   }
}

Die Performance-Steigerung ist beachtlich. In ersten Tests konnte ich eine Reduzierung der Response-Größe um bis zu 30% feststellen.

via

Lokales Repository für externe Bibliotheken

Ab und an kann es vorkommen, dass man eine Java-Bibliothek in seinem Play-Projekt benötigt die nicht in einem öffentlichen Maven-Repository zu finden ist. Hier habe ich i.d.R die Bibliothek dann meistens innerhalb eines separaten Ordners gespeichert und nach dem Deployment einfach in den /lib Ordner kopiert. Alles andere als schön, weshalb ich schon länger nach einer Lösung dafür gesucht habe.

Play bietet die Möglichkeit innerhalb der dependencies.yml ein lokales Repository festzulegen, aus dem die Java-Bibliothek dann geladen wird.

Beispiel

require:
    - play -> crud
    - provided -> DateHelper 1.0
repositories:
    - provided:
        type:       local
        artifact:   "${application.path}/jar/[module]-[revision].jar"
        contains:
            - provided -> *

Führt man den Befehl

play deps --sync

aus, wird die Bibliothek aus dem definierte Ordner (hier: “jar”) wie alle anderen Abhängigkeiten in den /lib Ordern kopiert. Der Ordner “jar” muss dafür im Play-Projekt erstellt werden und kann natürlich auch anders heißen.

via

Vorschau auf Play! 2.0

Guillaume Bort hat gestern in der Play! Mailingliste eine erste Vorschau auf das Play Framework 2.0 gegeben. Ein Fokus des anstehenden Major Release ist die nahtlose Integration von Scala. In der neuen Version wird es nicht mehr nötig sein Scala als weiteres Modul einbinden zu müssen, sondern Scala und natürlich Java werden nativ unterstützt. Ebenfalls neu ist ein neues Build-System (SBT), ein noch weiterer Fokus auf asynchrone Requests durch die Einbindung von Akka, sowie eine weitere Abstraktion des Datenbank-Layers.

Mehr Informationen findet man auch auf der offiziellen “Introducing Play 2.0″-Seite. Ein erstes Preview steht ebenfalls zum Download bereit.

Datei-Upload mit Play

Ein häufiges Anwendungsszenario ist die Dateiübertragung vom Client auf den Server. Dabei stellt sich eine Glaubensfrage: Wie werden die Daten auf dem Server gespeichert? Entweder man speichert die Daten direkt als Datei oder man legt die Daten in der Datenbank ab. Bei Lunatech Research findet man einen sehr guten Artikel zu diesem Thema.

Play im Produktiveinsatz

Das Play Framework ist mit seinen aktuell 3 Jahren noch ein recht junges Framework. Auch hat es (noch) keine große Entwicklergemeinde in der man um Hilfe fragen kann wenn man einmal auf Probleme stößt. Auch die Dokumentation ist zwar ausreichend, aber an der ein oder anderen Stelle vielleicht nicht umfassend genug. Darüber hinaus ist der Name “Play” IMHO nicht unbedingt günstig gewählt um Jemanden von dem Framework zu überzeugen. Gleichwohl Play mit seinen technischen Ideen und Konzepten überzeugen kann. Mit einem Framework wie Spring verbindet man allein vom Namen her gleich eine größere “Mächtigkeit”, obwohl auch bei Spring mit ähnlichen Technologien gearbeitet wird. Wie schlägt sich also das Play Framework im Produktiveinsatz?

Die Play-Homepage selbst ist mit Play gemacht und liefert 100.000 Request/Tag ohne Probleme aus. Auf subbu.org wurde vor kurzem das Play Framework mit Node.js, einem hochperformanten JavaScript IO-Framework, vergleichen. Dabei stellte sich heraus, dass Play zumindest in einigen Bereichen, mit Node.js mithalten kann. Weitere Erfahrungsberichte findet man hier.

Einen fundierten Vergleich von Play zu bekannteren Java-Frameworks gibt es aktuell (leider) noch nicht. Die bisherigen Erfahrungsberichte sprechen aber ganz klar dafür, dass man sich bei der Technologie-Auswahl nicht von subjektiven Eindrücken täuschen lassen sollte, sondern auch einem junge und vielleicht noch nicht so bekannten Framework wir Play in jeder Hinsicht eine Chance geben sollte.