bcrypt integration in MyBB: MyBBcrypt

Anmerkung: Die Software befindet sich noch in Entwicklung. Der Mod für MyBB ist bereits fertig und einsetzbar, allerdings nur über GitHubverfügbar. Download und Anleitung folgen sobald das Migrations-Plugin fertig ist.

MyBBcrypt Screenshot

MyBBcrypt – You know you want your users to be safe!

MyBB ist die Software meiner Wahl, wenn es um Foren geht. Es gibt viele Themes und Plugins, alles ist gut dokumentiert, und es ist kostenlos. Seit Version >1.2 ist die Forensoftware auch relativ sicher (Ausnahmen bestätigen die Regel…). Allerdings ist relativ sicher natürlich nicht sicher genug.
Sollte es jemals dazu kommen, dass ein Angreifer Zugriff auf die Datenbank hat, wäre das eine totale Katastrophe. Tausende User-Daten könnten entwendet werden, dabei wären die Passwörter sicher das wertvollste.
MyBB verwendet standardmäßig gesalzene MD5 Hashes. Das ist schonmal gut, besser als nur md5, allerdings kann man mit Software wie HashCat mehrere Millionen Passwörter pro Sekunde ausprobieren, daher gilt md5 generell nicht mehr als sicher.

bcrypt

Ein besseres Verfahren ist der Blowfish Algorithmus. Der durch bcrypt bereitgestellte Algorithmus gilt insbesondere unter IT-Sicherheitsexperten als sehr sicher. Es gibt noch keinen bekannten, effektiven Angriff auf das Verfahren. Außerdem verwendet bcrypt immer einen Salt. Das ganze wird immer wieder gehasht, wodurch sich natürlich die Ausführungszeit deutlich verlängert. Auf meinem 1,66EUR/Monat Webspace dauert es 0,4sek länger, einen 4096 mal gehashten bcrypt Hash zu erstellen, als einen md5(md5($salt).md5($pw)) hash zu erstellen (diesen Algorithmus verwendet MyBB). Klar, es ist fast eine halbe Sekunde mehr Ladezeit, allerdings wird diese halbe Sekunde nur beim Login benötigt. Ein Angreifer, der die Hashes brute-forcen will, braucht bei JEDER möglichen Kombination mehr Zeit, was es sehr schwierig macht, solche Hashes zu knacken. Wählt man als Nutzer ein Passwort, welches nicht in Wortlisten vorkommt, ist man schon sehr sicher.
Hätten LinkedIn, LastFM, eHarmony, Gamigo (usw…) allesamt bcrypt verwendet, wären höchstens die Passwörter geknackt worden, welche durch Wortlisten auffindbar sind. Durch einfaches MD5 konnten aber auch komplexere Passwörter gecrackt werden.
Leider Unterstützt MyBB noch kein bcrypt von Werk aus, eine Änderung des Hash-Algorithmus wird vor MyBB 2.0 auch nicht erfolgen (Quelle).
Betreiber großer Foren sind somit in die Ecke gedrängt. Sie müssen manuell ändern, viele scheuen den Aufwand. Daher bin ich dabei, eine MyBB Version mit integriertem bcrypt zu entwickeln:

Die Lösung

MyBBcrypt – so heißt der Mod für MyBB – ist Open Source, und darf von jedem verwendet werden. Das Projekt ist auf GitHub auffindbar, falls Jemand bei der Entwicklung und Instandhaltung helfen will: bitte bei mir melden.
MyBBcrypt ist zur Zeit nur als neue Installation nutzbar, für bestehende Foren wird bald ein PlugIn verfügbar sein, damit die Datenbank einfach konvertiert werden kann.
Als Algorithmus wird crypt($salted_pw, $randomsalt); genutzt, somit ist auf jeden Fall gewährleistet, dass alle Foren kompatibel sind. Das Plugin wird nur die passwort-Hashes der Benutzer mit einem zufälligen Salt mittels bcrypt hashen.
Damit der neue Algorithmus zum Login (und für andere Passwort-Operationen) genutzt werden kann, müssen 3 Dateien ausgetauscht werden:

  • inc/functions_user.php
  • inc/datahandlers/user.php
  • install/index.php

functions_user.php stellt Funktionen zum Login bereit, die user.php Funktionen wie Passwort-Änderung. Die index.php in /install muss nur angepasst werden, falls es sich im eine Neuinstallation handelt (Dort wird das Passwort des Admin-Accounts erstellt).

Updates und Kompatiblität

Das Forum bleibt update-fähig. So lange keine der 3 Dateien ersetzt wird, bleibt die bcrypt Integration intakt. In Zukunft muss man nur darauf achten, ob eine der 3 Dateien in einem Update modifiziert wird.
Wie bereits erwähnt, ist der Mod kompatibel mit allen Versionen von MyBB. Es muss nur der Blowfish-Algorithmus in PHP verfügbar sein. Dies ist ab PHP 5.3.0 gewährleistet, vorherige Versionen brauchen entsprechende System-libraries. Mit folgendem Code kann auf Kompatibilität hin geprüft werden:

<!--?php if (CRYPT_BLOWFISH == 1)  echo 'Kompatibel'; else  echo 'Nicht kompatibel'; ?-->

Wird der Algorithmus von MyBB jemals so geändert, dass der Mod nicht mehr kompatibel ist, muss nur ein Plugin installiert werden, welches jedes Passwort in der Datenbank nach Login des Users erneuert. In der aktuellen Version verzichte ist darauf, dieses Verfahren zu nutzen, um „reine“ bcrypt Hashes zu erhalten, da es einfacher ist, sofort alle Passwörter zu konvertieren, als darauf zu warten, dass sich jeder Nutzer einmal anmeldet.
Im Hinblick auf zukünftige Versionen, kann MyBBcrypt also bedenkenlos installiert werden.

Der Code

Die Details zum Code könnt ihr auf GitHub entnehmen, das Prinzip der Änderungen ist immer das Selbe:
Anstatt den einfach gesalzenen Passworthash in die Datenbank einzutragen / zu überprüfen, wird der Passworthash mit bcrypt gehasht. Bei Passwort-Änderung wird ein zufälliger Salt generiert. Dieser Salt ist im Passworthash mit enthalten, er muss also nicht separat gespeichert werden.

Beispiel: inc/functions_user.php Zeile 107:

/**
 * Checks a password with a supplied uid.
 *
 * @param int The user id.
 * @param string The plain-text password.
 * @param string An optional user data array.
 * @return boolean|array False when not valid, user data array when valid.
 */
function validate_password_from_uid($uid, $password, $user = array())
{
	global $db, $mybb;
	if($mybb->user['uid'] == $uid)
	{
		$user = $mybb->user;
	}
	if(!$user['password'])
	{
		$query = $db->simple_select("users", "uid,username,password,salt,loginkey,usergroup", "uid='".intval($uid)."'", array('limit' => 1));
		$user = $db->fetch_array($query);
	}
	if(!$user['salt'])
	{
		// Generate a salt for this user and assume the password stored in db is a plain md5 password
		$user['salt'] = generate_salt();
		// salt the password w/ the new salt, then bcrypt it (use a new bcrypt salt aswell)
		$user['password'] = crypt(salt_password($user['password'], $user['salt']), generate_bcrypt_salt());
		$sql_array = array(
			"salt" => $user['salt'],
			"password" => $user['password']
		);
		$db->update_query("users", $sql_array, "uid='".$user['uid']."'", 1);
	}

	if(!$user['loginkey'])
	{
		$user['loginkey'] = generate_loginkey();
		$sql_array = array(
			"loginkey" => $user['loginkey']
		);
		$db->update_query("users", $sql_array, "uid = ".$user['uid'], 1);
	}
	//Check the password stored in DB against the specified password, use the salt
	//from the hash stored in the DB
	if($user['password'] === crypt(salt_password(md5($password), $user['salt']), $user['password']))
	{
		return $user;
	}
	else
	{
		return false;
	}
}

In Zeile 26 stand vorher nur

salt_password($user['password'], $user['salt'])

Dieser Hash wird zusätzlich mit bcrypt und einem zufälligen Salt gehasht.
Bei der Überprüfung des Passwortes in Zeile 44 wird der Eintrag in der Datenbank ($user[‚password‘]) mit dem Resultat des bcrypts des eingegebenen, gesalzenen Passwortes überprüft. In der crypt-Funktion wird der Eintrag aus der Datenbank als Salt genommen, da dieser immer gleich lang ist, nutzt die Funktion automatisch nur den Salt-Teil des Hashes in der Datenbank.

Credits

MyBB © MyBB Group, Lizenz: LGPL

Die von mir unternommenen Änderungen sind frei Nutzbar unter CC-BY-NC-SA 3.0 Lizenz.

Interessierte können das Projekt von GitHub Klonen und installieren, sobald das Plugin zur Migration fertig ist, werden beide Projekte zum einfachen Download mit Anleitung bereit gestellt.

MfG
Damon Dransfeld


Dieser Eintrag wurde veröffentlicht in PHP, Security und getagged , .
Bookmarken: Permanent-Link Schreibe einen Kommentar oder hinterlasse einen Trackback: Trackback-URL.

2 Kommentare

  1. Stefan
    Erstellt am 29. Juli 2012 um 11:40 | Permalink zum Kommentar

    Eine MyBB-Version 1.3 gab es nie.

  2. Erstellt am 31. Juli 2012 um 18:30 | Permalink zum Kommentar

    Danke, ist geändert. Die MyBB Versionen habe ich leider nicht so im Überblick, erst ab 1.4.1…
    MfG
    Damon

Achtung: Wordpress interpretiert bestimmte Zeichenfolgen als Markup und verändert diese. Nutzt für Programmcode lieber Gist oder PasteBin-Services und verlinkt die Code-Schnipsel.

Post a Comment

Ihre E-Mail wird niemals veröffentlicht oder verteilt. Benötigte Felder sind mit * markiert

*
*

Du kannst diese HTML Tags und Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>