vb.org Archive

vb.org Archive (https://vborg.vbsupport.ru/index.php)
-   vBulletin 4.x Add-ons (https://vborg.vbsupport.ru/forumdisplay.php?f=245)
-   -   Mini Mods - Secure BCrypt Password Hashing (https://vborg.vbsupport.ru/showthread.php?t=288450)

MegaManSec 09-28-2012 10:00 PM

Secure BCrypt Password Hashing
 
1 Attachment(s)
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!!

Quote:

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-...red-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!

hakkuo23 09-29-2012 04:10 AM

Thank you for the fast reply! I love you man!

hakkuo23 09-29-2012 04:25 AM

After I applied the changes I am unable to login, it says my password is incorrect :(

EDIT

Stupid me, there was an extra parenthesis in functions_login.php

I will respond if it works in a bit!

EDIT

No it does not work :( vBulletin v4.2.0

MentaL 09-29-2012 10:20 AM

excellent.

MegaManSec 09-29-2012 12:24 PM

Quote:

Originally Posted by hakkuo23 (Post 2369419)
After I applied the changes I am unable to login, it says my password is incorrect :(

EDIT

Stupid me, there was an extra parenthesis in functions_login.php

I will respond if it works in a bit!

EDIT

No it does not work :( vBulletin v4.2.0

Yes, all of your passwords would be reset, as the algorythum would change.

kh99 09-29-2012 06:59 PM

Since your new algorithm basically encrypts the original hash, I think you could actually write a function to go through and convert all the passwords so that existing members could log in without having to change their pw. But of course when it's uninstalled there's nothing else to be done but have everyone change their pw. Either way you might want to add a warning in the description.

Anyway, nice mod, I was thinking about something like this a while back but never got around to it.

MegaManSec 09-29-2012 07:55 PM

Quote:

Originally Posted by kh99 (Post 2369576)
Since your new algorithm basically encrypts the original hash, I think you could actually write a function to go through and convert all the passwords so that existing members could log in without having to change their pw. But of course when it's uninstalled there's nothing else to be done but have everyone change their pw. Either way you might want to add a warning in the description.

Anyway, nice mod, I was thinking about something like this a while back but never got around to it.

Filip(DragonByte-Tech) and I were working on somethbing like that, but it didn't work for some strange reason.

And yeah, it can only go 'one way'.

I'll add a disclaimer to the OP

Adrian Schneider 09-29-2012 08:54 PM

First off, thanks for trying to make vBulletin more secure. BCrypt is an excellent algorithm and much much better than md5. From my latest research, it's the industry standard.

However - you are going to all this work to properly store the password using BCrypt, but then you md5 it. As soon as you md5 it, you have lost all of that security :(.

Second - and this is just a future suggestion, you could have the system detect which password hash they are using, and check accordingly. This way you can update peoples passwords to the new system whenever they change their password (and probably mass-email everyone suggesting they do). but still authenticate the old hashes properly. Unfortunately the way it's implemented, nobody will want to use this except for starting new boards. It is possible.

Cheers

MegaManSec 09-29-2012 08:56 PM

Quote:

Originally Posted by Adrian Schneider (Post 2369619)
First off, thanks for trying to make vBulletin more secure. BCrypt is an excellent algorithm and much much better than md5. From my latest research, it's the industry standard.

However - you are going to all this work to properly store the password using BCrypt, but then you md5 it. As soon as you md5 it, you have lost all of that security :(.

Second - and this is just a future suggestion, you could have the system detect which password hash they are using, and check accordingly. This way you can update peoples passwords to the new system whenever they change their password (and probably mass-email everyone suggesting they do). but still authenticate the old hashes properly. Unfortunately the way it's implemented, nobody will want to use this except for starting new boards. It is possible.

Cheers

Er, once I MD5 it it does not lose security. if anything, it makes it more secure(by 0.00001 of a percent, though)
I'm currently crteating the 'auto-bcrypt' pwd encrypter for it. it'll be done soon.

Adrian Schneider 09-29-2012 09:03 PM

No - once you md5 it, you have lost all of the security. You are still succeptable to md5 collissions which is md5's biggset weakness.


All times are GMT. The time now is 12:16 AM.

Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2025, vBulletin Solutions Inc.

X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.01269 seconds
  • Memory Usage 1,761KB
  • Queries Executed 10 (?)
More Information
Template Usage:
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (9)bbcode_code_printable
  • (4)bbcode_quote_printable
  • (1)footer
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (6)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (2)pagenav_pagelink
  • (1)post_thanks_navbar_search
  • (1)printthread
  • (10)printthreadbit
  • (1)spacer_close
  • (1)spacer_open 

Phrase Groups Available:
  • global
  • postbit
  • showthread
Included Files:
  • ./printthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/class_bbcode_alt.php
  • ./includes/class_bbcode.php
  • ./includes/functions_bigthree.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • printthread_start
  • pagenav_page
  • pagenav_complete
  • bbcode_fetch_tags
  • bbcode_create
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • printthread_post
  • printthread_complete