I am exporting, by scraping it with http requests since the host won’t give me database access, a forum and importing it into a mysql database for vbulletin.
In vbulletin users have unique password salts, and it generates password hashes using this algorithm:
$hash = md5(md5($plaintext) . $salt);
I’m using a python script to read stored data from my sqlite database of user information to generate a new password and salt for users, then storing that data into the mysql database so vbulletin can use it.
My problem is that python is changing the value of strings in unexpected ways. I’m testing my script using a known password and salt to compare the hashes. However, the salt that I’m using is this:
D(A3*w/lo6CooMc,H!0!2Z3d@O&R
When I try to store that in python, when I retrieve the string I get this:
D(Ax03*w/lo6Coo\Mc,H!0!2Z3d@O&R
This is the python code I’m using to mimic the vbulletin hashing algorithm:
salt = 'D(A3*w/lo6CooMc,H!0!2Z3d@O&R' password = hashlib.md5() password.update('*snipped password*') password = password.hexdigest() password_hash = hashlib.md5() password_hash.update(password + salt) password_hash = password_hash.hexdigest()
For comparison, this PHP matches what vbulletin stores as the password hash in the database:
$plaintext = '*snipped password*'; $salt = 'D(A3*w/lo6CooMc,H!0!2Z3d@O&R'; $hash = md5(md5($plaintext) . $salt);
$hash matches what vbulletin stores and password_hash does not. What am I doing wrong to cause the difference?
Advertisement
Answer
The way you’re defining salt
is the problem. You have to either make it a raw string:
salt = r'D(A3*w/lo6CooMc,H!0!2Z3d@O&R'
Or escape the backslashes:
salt = 'D(A\3*w/lo6Coo\Mc,H!0!2Z3d@O&R'
Otherwise, 3
is interpreted as the escape sequence for the character with a character code of 3
.
Also, for readability, you may want to make an md5
function:
def md5(text): return hashlib.md5(text).hexdigest() hash = md5(md5(plaintext) + salt)