Password hasher for vBulletin?

78 views
Skip to first unread message

jorr...@gmail.com

unread,
Mar 15, 2016, 11:54:32 AM3/15/16
to Django users
I'm converting an old vBulletin 3.8 installation to a Django web app and I'm wondering if I can migrate users over with their passwords intact.

vBulletin uses md5(md5(password) + salt) to hash its passwords, would any of Django's built-in password hashers work with this out of the box?

Some of the salts also contain the $ character, I'm guessing that's a big problem?

I'm wondering if it would be easiest (or even possible) to write a custom password hasher for this or just have everyone reset their passwords once the new site goes live.

Any thoughts on this would be appreciated!

Tim Graham

unread,
Mar 15, 2016, 11:59:39 AM3/15/16
to Django users
Take a look at https://docs.djangoproject.com/en/stable/topics/auth/passwords/#password-upgrading-without-requiring-a-login

Instead of SHA1PasswordHasher().encode() you'll want to use vBulletin's hashing algorithm.

jorr...@gmail.com

unread,
Mar 15, 2016, 7:26:59 PM3/15/16
to Django users
Holy crap, you guys have really thought of everything! Love it!

Unfortunately this doesn't work on all users because some salts contain the $ character which gives the assert salt and '$' not in salt error. Is there a workaround for this?

Tim Graham

unread,
Mar 15, 2016, 7:54:18 PM3/15/16
to Django users
I can't think of anything offhand besides implementing your own PBKDF2PasswordHasher subclass which does its own more sophisticated splitting that doesn't get confused by dollar signs in the salt.

jorr...@gmail.com

unread,
Mar 16, 2016, 7:05:33 PM3/16/16
to Django users
Thanks for the help!

If anyone looks at this in the future, this is the code I ended up using:

hashers.py
class PBKDF2WrappedvBPasswordHasher(PBKDF2PasswordHasher):
algorithm = 'pbkdf2_vB'

def encode_vB_hash(self, vB_hash, salt, iterations=None):
return super(PBKDF2WrappedvBPasswordHasher, self).encode(vB_hash, salt, iterations)

def encode(self, password, salt, iterations=None):
vB_hash = hashlib.md5(hashlib.md5(force_bytes(password)).hexdigest() + force_bytes(salt)).hexdigest()
return self.encode_vB_hash(vB_hash, salt, iterations)

settings.py
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'members.hashers.PBKDF2WrappedvBPasswordHasher',
]

Importing vBulletin password in the Django format, assuming 2 columns for vBulletin containing salt and MD5 hash, respectively:
password='pbkdf2_vB' + '$' + row[5] + '$' + row[6],

Upgrading to pbkdf2_vB hash:
hasher = PBKDF2WrappedvBPasswordHasher()
algorithm, salt, vB_hash = user.password.split('$', 2)
user.password = hasher.encode_vB_hash(vB_hash, salt)

jorr...@gmail.com

unread,
Jun 23, 2016, 11:09:32 AM6/23/16
to Django users
As a follow-up question to this... this line gives the error "Can't convert 'bytes' object to str implicitly":


vB_hash = hashlib.md5(hashlib.md5(force_bytes(password)).hexdigest() + force_bytes(salt)).hexdigest()

Do I need to insert a str() somewhere?

ludovic coues

unread,
Jun 23, 2016, 5:24:25 PM6/23/16
to django...@googlegroups.com
Do you have extra good reason to call hashlib function with a variable
called password ?

If you simply want to hash user password, django provide a few
function for that job [1].

it's used like that:
>>> from django.contrib.auth.hashers import make_password, >>> check_password
>>> pwd = make_password("foobar")
>>> checkpassword("foobar", pwd)
Notice how you don't have to worry about thing like salt. Django take
care of that.

To answer your question, you are trying to concatenate
`hashlib.md5(force_bytes(password)).hexdigest()`, which is a str and
`force_bytes(salt)`, which is a bytes. You can add a str() aroung the
second part or a force_bytes around the first one.


[1] https://docs.djangoproject.com/en/1.9/topics/auth/passwords/
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/c722dda1-009f-4bb0-b7a7-99bd9ffb2bbc%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--

Cordialement, Coues Ludovic
+336 148 743 42
Reply all
Reply to author
Forward
0 new messages