为什么werkzeug的`generate_password_hash`输出不固定?

33 投票
1 回答
30287 浏览
提问于 2025-04-18 05:09

当我多次运行 werkzeug.security.generate_password_hash("Same password") (文档) 时,输出的结果每次都不一样。

我哪里做错了?为什么结果不固定呢?

1 个回答

75

密码是经过加盐处理的,没错。加盐是指在对密码进行哈希处理之前,先添加一些随机生成的字符,这样可以确保生成的哈希值不会被用在彩虹表攻击中。

因为每次调用这个函数时,盐都是随机生成的,所以得到的密码哈希值也会不同。返回的哈希值中包含了生成的盐,这样就能正确地验证密码。

示例:

>>> from werkzeug.security import generate_password_hash
>>> generate_password_hash('foobar')
'pbkdf2:sha1:1000$tYqN0VeL$2ee2568465fa30c1e6680196f8bb9eb0d2ca072d'
>>> generate_password_hash('foobar')
'pbkdf2:sha1:1000$XHj5nlLU$bb9a81bc54e7d6e11d9ab212cd143e768ea6225d'

这两个字符串不同,但它们包含足够的信息来验证密码,因为每个哈希中都包含了生成的盐:

# pbkdf2:sha1:1000$tYqN0VeL$2ee2568465fa30c1e6680196f8bb9eb0d2ca072d
  ^^^^^^^^^^^^^^^^   salt   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      algo info    ^^^^^^^^        actual hash of the password
  (PBKDF2 applied SHA1 1000 times)

因为一个的随机盐是tYqN0VeL,而另一个是XHj5nlLU,所以得到的哈希值也不同。

密码foobar仍然可以与任意一个哈希值进行验证:

>>> from werkzeug.security import check_password_hash
>>> check_password_hash('pbkdf2:sha1:1000$tYqN0VeL$2ee2568465fa30c1e6680196f8bb9eb0d2ca072d', 'foobar')
True
>>> check_password_hash('pbkdf2:sha1:1000$XHj5nlLU$bb9a81bc54e7d6e11d9ab212cd143e768ea6225d', 'foobar')
True

另外可以参考

撰写回答