Jungle is now SHA-1 secure

Heute hatte ich trotz Grippe ein wenig Zeit und geistige Aufmerksamkeit für Jungle übrig.
Von einer anständigen Applikation erwarte ich, daß sie Passwörter nicht im Klartext sondern in irgendeinem zumindest halbwegs sicheren Hash-Verfahren in der Datenbank ablegt. Im Prinzip eine einfache Angelegenheit… Bevor man einen User anlegt, hasht man das eingegebene Passwort und vergleicht dann immer den Hash beim Authentifizieren mit dem in der Datenbank abgelegten.
Mehrere Dinge braucht man hierfür:

  • Die Implementierung der Hashfunktion
  • Zugriff auf die Datenbank
  • Etwas zum Anlegen von Benutzern
  • Etwas zum Authentizieren.

Also… Die Implementierung der Hashfunktion. Kurz nachgedacht, richtig, da gabs ja schon was: java.security.MessageDigest.

MessageDigest sha1 = null;
try {
    sha1 = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e1) {
    log.fatal("sha-1 message digester not present!");
}

Das Ding hat dann eine digest()-Methode und mit ein wenig String-Automagie (new String, getBytes) wird dann daraus auch eine anständige Umwandlung mit der man arbeiten kann.

Nächster Schritt: Zugriff auf die Datenbank… Piece of cake! Wir sind in Seam, ein einfaches:

@In EntityManager em;

sollte genügen. So sagt auch die Doku…. Doch leider leider lügt sie… Dies merkt man, wenn man plötzlich keinen Zugriff mehr auf seinen Authenticator bekommt, um man erst nach ein wenig Stacktrace-Gewühle zu Trage tritt, daß er hier wohl keinen EntityManager injecten kann, weil man sich jenseits von Zeit und Raum befindet.

*grml* *grml*

Also Beispielcode wälzen…. Schau an… Alle Authenticators in den Beispielen sind als Stateless Session Beans modelliert in dem der EntityManager so in die Bean kommt:

@PersistenceContext EntityManager em;

Na mir solls recht sein. Rasch ummodelliert… Ha! Geht!

Etwas zum Anlegen der Benutzer… Gut, okay… Simpel… Rasch ein Formular gestrickt und einen Manager geschrieben, der ungefähr so aussieht:

@Name("userManager")
public class UserManagement extends EntityHome {
@Logger Log log;
@Override
public String persist() {
MessageDigest sha1 = null;
try {
sha1 = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e1) {
log.fatal("message digester not present!");
}
try {
getInstance().setPassword(
new String(sha1.digest(
getInstance().getPassword()
.getBytes())));
return super.persist();
} catch (Exception e) {
log.error(e.toString());
}
return "no";
}
}

Das wars…

Punkt 4 – Wo man sich einloggt… Gibts schon in Seam, muss ich nix machen.

So… Jetzt hab ich User-Logins mit SHA-1. Im Prinzip extrem schmerzfrei, wenn nicht die Sache mit der fehlerhaften Injection wäre.
Demnächst dann mehr hier… :)

Einen Kommentar schreiben