Back to vBulletin 4.x Add-ons

Secure BCrypt Password Hashing
Mod Version: 2.00, by MegaManSec

vB Version: 4.x.x Rating: (3 votes - 5.00 average) Installs: 15
Released: 29 Sep 2012 Last Update: Never Downloads: 0
Not Supported Code Changes Re-usable Code Translations  

This is a 'howto' for using bcrypt for your password hashs, instead of the default vBulletin one, which is highly insecure.

Remember, backup your database before doing this!!

bcrypt is a key derivation function for passwords designed by Niels Provos and David Mazières, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

More information about BCrypt can be found here: http://codahale.com/how-to-safely-store-a-password/ - http://phpmaster.com/why-you-should-use-bcrypt-to-hash-stored-passwords/

tl;dr: if you want to be moar secure, use bcrypt.

" How much slower is bcrypt than, say, MD5? Depends on the work factor. Using a work factor of 12, bcrypt hashes the password 'password' in about 0.3 seconds on my laptop. MD5, on the other hand, takes less than a nanosecond."

BEFORE YOU DO THIS, PLEASE CREATE A .PHP FILE WITH THIS IN IT
Code:
<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
    echo "CRYPT_BLOWFISH is enabled!";
}
else {
    echo "CRYPT_BLOWFISH is not available";
}
If it is not available, please contact your host.

/includes/functions.php
Add this to the end, just before the footer message.

Code:
/**
 * 
 * Hash 'password' using the crypt() function w/  bcrypt
 * Use the first 21 characters of the MD5(strrev($salt)) as our bcrypt salt
 * Return the MD5 return of this crypt() call, to maintain database functionality. The main part of our security is kept(making hashing, thus cracking, longer).
 * This should always be called like hash_password_bcrypt(md5(md5($password) . $salt), $salt)
 **/
function hash_password_bcrypt($password, $salt) {
       //You may set this to your liking. A higher cost means it will take longer for the password to hash. 15 seems to be a good value.
       $cost = 15; // must be in range 04 - 31
     return md5(crypt($password, '$2y$' . $cost . '$' . substr(md5(strrev($salt)),0,21) . '$'));
}


includes/class_dm_user.php
Now..

Find this:
Code:
                        if ($password == md5(md5($this->fetch_field('username')) . $salt))
and replace it with this:
Code:
                        if ($password == $this->hash_password($this->fetch_field('username'), $salt))
(Note to self.. Why does the original code use this implicit hashing rather than the hash_password function? hash_password takes cares of md5 stuff already if it's not already md5)

Then, on the same file, replace this:
Code:
return md5($password . $salt);
with this
Code:
//No need to md5($password), since it is already md5'd above.
return hash_password_bcrypt(md5($password . $salt), $salt);


includes/functions_login.php

Find this:
Code:
                       $vbulletin->userinfo['password'] != iif($password AND !$md5password, md5(md5($password) . $vbulletin->userinfo['salt']), '') AND
                       $vbulletin->userinfo['password'] != iif($md5password, md5($md5password . $vbulletin->userinfo['salt']), '') AND
                       $vbulletin->userinfo['password'] != iif($md5password_utf, md5($md5password_utf . $vbulletin->userinfo['salt']), '')
And replace it with this:

Code:
                       $vbulletin->userinfo['password'] != iif($password AND !$md5password, hash_password_bcrypt(md5(md5($password) . $vbulletin->userinfo['salt']), $vbulletin->userinfo['salt']), '') AND
                       $vbulletin->userinfo['password'] != iif($md5password, hash_password_bcrypt(md5($md5password . $vbulletin->userinfo['salt']), $vbulletin->userinfo['salt']), '') AND
                       $vbulletin->userinfo['password'] != iif($md5password_utf, hash_password_bcrypt(md5($md5password_utf. $vbulletin->userinfo['salt']), $vbulletin->userinfo['salt']), '')

So effectively, we are hashing the password using the normal vBulletin way of
md5(md5($password) . $vbulletin->userinfo['salt'])
however after doing that, we then run hash_password_bcrypt() around it.

By doing it this way, we can now convert our old hashes to the new bcrypt method.

Create a file called "convert.php", with the contents:
Code:
<?php
require("./global.php");
set_time_limit(0);
ini_set('max_execution_time',0);
$q = $db->query_read("select userid, username, password, salt from user WHERE password != ''");
echo "Updating " . $db->num_rows($q) . " accounts.<br />\n";
while($r = $db->fetch_array($q)){
    $db->query_write("UPDATE user SET password = '" . hash_password_bcrypt($r['password'], $r['salt']) . "' WHERE userid = '" . $r['userid'] . "'");
     echo "Updated password for " . htmlspecialchars($r['username']) . "<br />\n";
}
echo "Finished.<br />\n";
?>
I recommend running the script in a terminal, however you may be able to run it in a browser. If you run it in the browser, it may time out!

Download

No files for download.


vblts.ru supports vBulletin®, 2022-2024