为什么werkzeugs的'generate_password_hash`的输出不是常数?

时间:2014-05-02 16:09:13

标签: python flask password-encryption

当我多次运行werkzeug.security.generate_password_hash("Same password")docs)时,每次输出都不同。

我做错了什么?为什么不恒定?

1 个答案:

答案 0 :(得分:38)

密码 salted ,是的。在散列之前将salt添加到密码中,以确保哈希在rainbow table attack中不可用。

由于每次调用函数时都会随机生成salt,因此生成的密码哈希也不同。返回的哈希包括生成的salt,因此仍然可以正确验证密码。

演示:

>>> 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)

因为随机盐为tYqN0VeLXHj5nlLU,所产生的哈希值也不同。

仍然可以针对任一哈希验证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

另见