Thanks for the help!
If anyone looks at this in the future, this is the code I ended up using:
hashers.pyclass 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.pyPASSWORD_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)