1

我正在导出,因为主机不会给我数据库访问权限,所以通过 http 请求抓取它,一个论坛并将其导入到 vbulletin 的 mysql 数据库中。

在 vbulletin 中,用户具有唯一的密码盐,它使用以下算法生成密码哈希:

$hash = md5(md5($plaintext) . $salt);

我正在使用 python 脚本从我的用户信息的 sqlite 数据库中读取存储的数据,为用户生成新的密码和盐,然后将该数据存储到 mysql 数据库中,以便 vbulletin 可以使用它。

我的问题是 python 正在以意想不到的方式改变字符串的值。我正在使用已知密码和盐测试我的脚本以比较哈希值。但是,我使用的盐是这样的:

D(A\3*w/lo6Coo\Mc,H!0!2Z3d@O&R

当我尝试将其存储在 python 中时,当我检索字符串时,我得到了这个:

D(A\x03*w/lo6Coo\\Mc,H!0!2Z3d@O&R

这是我用来模仿 vbulletin 散列算法的 python 代码:

salt = 'D(A\3*w/lo6Coo\Mc,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()

为了比较,这个 PHP 匹配 vbulletin 作为密码哈希存储在数据库中的内容:

$plaintext = '*snipped password*';
$salt = 'D(A\3*w/lo6Coo\Mc,H!0!2Z3d@O&R';

$hash = md5(md5($plaintext) . $salt);

$hash 匹配 vbulletin 存储的内容,而 password_hash 不匹配。我做错了什么导致差异?

4

2 回答 2

2

您定义的方式salt是问题所在。您必须将其设为原始字符串:

salt = r'D(A\3*w/lo6Coo\Mc,H!0!2Z3d@O&R'

或转义反斜杠:

salt = 'D(A\\3*w/lo6Coo\\Mc,H!0!2Z3d@O&R'

否则,\3被解释为字符代码为 的字符的转义序列3

此外,为了便于阅读,您可能需要创建一个md5函数:

def md5(text):
    return hashlib.md5(text).hexdigest()

hash = md5(md5(plaintext) + salt)
于 2013-06-12T21:50:04.150 回答
0

对于今天使用此解决方案的人,请勿使用 md5 存储散列密码。

于 2021-07-01T19:01:14.603 回答