密码是加盐的。在进行哈希之前,将盐添加到密码中,以确保哈希无法用于彩虹表攻击。
由于每次调用函数时都会随机生成盐,因此生成的密码哈希值也不同。返回的哈希值包括生成的盐,以便能够正确验证密码。
演示:
>>> 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
另请参见