为什么werkzeug的`generate_password_hash`输出不固定?
当我多次运行 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
另外可以参考
- 你能帮我理解什么是加密“盐”吗? (Cryptography.SE)
- 为什么使用盐更安全? (Security.SE)