为何Passlib生成的pbkdf2-sha512哈希与目标密码条目不符?
问题:Passlib生成的PBKDF2-SHA512哈希与目标条目不一致
我的密码文件中有如下哈希条目:
$pbkdf2-sha512$25000$K0XonfPe29vbW0up9X5vDQ$3scRqpOxF29.tqPWpKJmcFvpb8/SFtbAiI2UlrM473B3tD.Mw8xzamNaE0KpZApTc7N1stlK/vvdUl9xna6wIA
已知生成该条目的密码为foobar,根据Passlib文档解析出:pbkdf2-sha512为哈希算法、25000为迭代次数、K0XonfPe29vbW0up9X5vDQ为盐的适配Base64编码、后续字符串为派生密钥。
我编写了如下Python代码:
from passlib.utils.binary import ab64_decode from passlib.hash import pbkdf2_sha512 salt = 'K0XonfPe29vbW0up9X5vDQ' salt_decoded = ab64_decode(salt) hashed_string = pbkdf2_sha512.hash('foobar', rounds=25000, salt=salt_decoded)
但生成的哈希值为:
$pbkdf2-sha512$25000$K0XonfPe29vbW0up9X5vDQ$ekYyFII.tyf0kWX1BBkICleOTCWIjDbKtGQ4iAU/qvGSmWQf.SAcFcJu6ZGwFFQMe4Kws2ngw.pgGaVe7F/I2g
与目标条目不一致,尝试多种编解码组合仍无效,请问问题出在哪里?
问题排查与解决方法
第一步:验证Passlib能否正确识别目标哈希
先确认Passlib本身能否验证目标哈希和密码的匹配性,运行以下代码:
from passlib.hash import pbkdf2_sha512 target_hash = "$pbkdf2-sha512$25000$K0XonfPe29vbW0up9X5vDQ$3scRqpOxF29.tqPWpKJmcFvpb8/SFtbAiI2UlrM473B3tD.Mw8xzamNaE0KpZApTc7N1stlK/vvdUl9xna6wIA" print(pbkdf2_sha512.verify("foobar", target_hash))
如果返回True
说明Passlib能正确解析目标哈希的参数,问题出在手动指定参数的细节上:
- 改用
using()方法生成哈希:尝试通过配置对象生成哈希,避免参数传递的隐性问题:from passlib.utils.binary import ab64_decode from passlib.hash import pbkdf2_sha512 salt = 'K0XonfPe29vbW0up9X5vDQ' salt_decoded = ab64_decode(salt) hash_config = pbkdf2_sha512.using(rounds=25000, salt=salt_decoded) hashed_string = hash_config.hash('foobar') print(hashed_string) - 升级Passlib版本:不同版本的Passlib在PBKDF2实现或AB64编码处理上可能存在差异,执行
pip install --upgrade passlib升级到最新版后重试。
如果返回False
说明对目标哈希的参数解析有误,尝试以下调整:
- 用标准Base64解码盐:部分PBKDF2实现可能使用标准Base64而非Passlib的AB64编码,尝试添加填充后解码:
import base64 from passlib.hash import pbkdf2_sha512 salt = 'K0XonfPe29vbW0up9X5vDQ' salt_padded = salt + '==' # 标准Base64需要补全填充位 salt_decoded = base64.b64decode(salt_padded) hashed_string = pbkdf2_sha512.hash('foobar', rounds=25000, salt=salt_decoded) print(hashed_string) - 检查密码编码:目标哈希生成时可能使用了非UTF-8编码(比如Latin-1),尝试转换编码后重试:
from passlib.utils.binary import ab64_decode from passlib.hash import pbkdf2_sha512 salt = 'K0XonfPe29vbW0up9X5vDQ' salt_decoded = ab64_decode(salt) # 尝试用Latin-1编码处理密码 hashed_string = pbkdf2_sha512.hash('foobar'.encode('latin-1').decode('latin-1'), rounds=25000, salt=salt_decoded) print(hashed_string) - 手动指定派生密钥长度:虽然Passlib的
pbkdf2_sha512默认dk_len为64字节(SHA512的输出长度),但仍可手动指定确认:from passlib.utils.binary import ab64_decode from passlib.hash import pbkdf2_sha512 salt = 'K0XonfPe29vbW0up9X5vDQ' salt_decoded = ab64_decode(salt) hashed_string = pbkdf2_sha512.hash('foobar', rounds=25000, salt=salt_decoded, dk_len=64) print(hashed_string)
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

