Du bist nicht angemeldet.

1

Donnerstag, 29. März 2012, 15:42

PasswortHashing

HeyHo,

[Rumgelaber]

im Internet wird immer wieder auf BCrypt geschworen, ein Verfahren, was sicherer als MD5, SHA1, ... ist, weil es darauf ausgelegt ist, einen möglichst "sicheren" Passwordhash zu erstellen und nicht den möglichst kleinen ;)
Dementsprechend ist es via. Bruteforce Attacken sehr viel schwieriger, die Passwörter zu knacken, weil ...

Zitat

A modern server can calculate the MD5 hash of about 330MB every second. If your users have passwords which are lowercase, alphanumeric, and 6 characters long, you can try every single possible password of that size in around 40 seconds.
... bei BCrypt nicht der Fall ist.

Man könnte also auf die Idee kommen, BCrypt auch in Java und im Emulator zu verwenden, schließlich ist BCrypt bei vielen anderen Sprachen an der Tagesordnung - BCrypt wird bei PHP z.B. beim "crypt"-Command aufgerufen,

[Vorbereitungen]

Downloaden: http://www.mindrot.org/projects/jBCrypt/#download

[Datenbank-Änderung]

Account-Struktur:

Änderungen:
password von varchar(20) zu text machen:

PHP-Quelltext

1
<?php ALTER TABLE `accounts` CHANGE `password` `password` TEXT CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ?>

Hinzufügen von der Spalte salt:

PHP-Quelltext

1
<?php ALTER TABLE `accounts` ADD `salt` TEXT NULL DEFAULT NULL AFTER `password` ?>


[Java-Quelltext]
Join-Channel-Handler. Einsetzen:

PHP-Quelltext

1
<?php if (nickname.isEmpty()) {            client.send(Popup.create("Problem", "Nickname fehlt", "#Um in den Chat eintreten zu können, müssen Sie _vorher einen Nick registrieren_.##Klicken Sie dazu auf der Webseite auf folgenden Button:##°>neu_reg.gif<°", 400, 300));            return;        }        PoolConnection pcon = ConnectionPool.getConnection();        PreparedStatement ps = null;        try {            Connection con = pcon.connect();            ps = con.prepareStatement("SELECT `id`, `name`, `password`, `salt` FROM `accounts` WHERE `name` = ?");            ps.setString(1, nickname);            ResultSet rs = ps.executeQuery();            if (!rs.next()) {                client.send(Popup.create("Problem", "Nick existiert nicht", String.format("#Der Nickname '%s' ist _nicht registriert_.##Um diesen Nicknamen zu registrieren klicken Sie auf der Webseite auf folgenden Button:##°>neu_reg.gif<°", nickname), 400, 300));                return;            }                        Integer id = rs.getInt("id");            nickname = rs.getString("name");                        if(rs.getString("salt") != null){                if(!BCrypt.checkpw(tokens[3], rs.getString("password"))){ //Falsches Passwort (NEW)                    client.send(Popup.create("Problem", "Falsches Passwort", String.format("#_Falsches Passwort_ für %s verwendet. Achten Sie auf mögliche Groß-/Kleinschreibung Ihres Passwortes.##°B>Passwort vergessen/funktioniert nicht mehr?|http://www.knuddels.de/pwd.html<r°##Um einen neuen Nicknamen zu registrieren, klicken Sie auf der Webseite den folgenden Button an:##°>neu_reg.gif<°", nickname), 400, 300));                    return;                }            }else{                String shaPassword = HexTool.hash("SHA1", tokens[3]);                if(!shaPassword.equals(rs.getString("password"))){ //Falsches Passwort (OLD)                    client.send(Popup.create("Problem", "Falsches Passwort", String.format("#_Falsches Passwort_ für %s verwendet. Achten Sie auf mögliche Groß-/Kleinschreibung Ihres Passwortes.##°B>Passwort vergessen/funktioniert nicht mehr?|http://www.knuddels.de/pwd.html<r°##Um einen neuen Nicknamen zu registrieren, klicken Sie auf der Webseite den folgenden Button an:##°>neu_reg.gif<°", nickname), 400, 300));                    return;                }else{ //Neuen PW Hash generieren + Abspeichern etc.                    String newSalt = BCrypt.gensalt();                    String hashedPassword = BCrypt.hashpw(tokens[3], newSalt);                    ps = con.prepareStatement("UPDATE `accounts` SET `password` = ?, `salt` = ? WHERE `name` = ?");                    ps.setString(1, hashedPassword);                    ps.setString(2, newSalt);                    ps.setString(3, nickname);                    ps.executeUpdate();                }            }            client.login(nickname);        } catch (SQLException e) { ?>

(Stelle sollte klar sein!)

Dann noch die BCrypt.java aus dem Download hinzufügen und ggf. den Import dazu hinzufügen.

Eigenschaften:
Password wird automatisch "umgehasht", d.h. beim neuen Login des Users, wird das alte Passwort durch das alte Ersetzt und der neue Algorithmus angewandt.

MfG

2

Donnerstag, 29. März 2012, 17:33

MD5 reicht auch locker, wenn man einen Salt benutzt. Dann ist es locker genauso sicher ;)
md5(salt + md5(pw)) oder umgekehrt, je nachdem.
Des weiteren ist dann keine zusätzliche Jar von Nöten.

Es haben sich bereits 2 registrierte Benutzer bedankt.

Benutzer, die sich für diesen Beitrag bedankt haben:

Nachto, Mentos

3

Freitag, 30. März 2012, 01:47

Danke für die Antwort - man fügt aber keine extra .jar ein, denn jBcrypt stellt den Source zur Verfügung, so dass man bequem die.Java hinzufügen kann. Das verwenden von dem MD5-Algorithmus sollte ja nicht zu schwer zu implementieren zu sein, nur wollte ich auf den BCrypt Algorithmus hinweisen und zeigen, wie man diesen verwendet.
MfG