【问题标题】:Salt in PBKDF2 - PythonPBKDF2 中的盐 - Python
【发布时间】:2017-01-31 12:12:15
【问题描述】:

我正在学习如何在使用 MySQL 和 Python 进行开发时保护密码,遵循 this tutorial

据我了解,userpassword 存储在数据库中哈希,salt 存储在未加密的一侧,这样我们就可以获取哈希密码和 salt,并使用 salt 重新哈希输入的密码,然后比较两者.

但是,当使用 PBKDF2(通过 passlib.hash.sha256_crypt() 函数)时,我不能设置自己的盐,只能设置它的大小。那么如何使用相同的盐重新加密密码以便比较两者?

【问题讨论】:

  • hashlib.pbkdf2_hmac() 吃盐。你用的是什么功能?
  • 我正在使用 pbkdf2_sha256.encrypt,遵循cyberciti.biz/python-tutorials/… 中的指南
  • 那个implementation 也需要盐。如果未指定,则会为您生成一个。
  • 我可以只做 pbkdf2_sha256.encrypt(arg, arg, salt='blabla235') 吗?
  • 请注意,返回的字符串包含盐,因此您不需要预先生成一个。该字符串的格式为$<type>$rounds=<rounds>$salt$hash,因此如果您想单独存储哈希值,您可以根据需要单独存储。

标签: python mysql python-3.x salt pbkdf2


【解决方案1】:

Passlib Password Hash interface 可以让您设置盐sizesalt 值本身。来自documentation on pbkdf2_sha256

  • salt (bytes) 可选盐字节。如果指定,长度必须在 0-1024 字节之间。如果未指定,将自动生成一个 16 字节的盐(建议这样做)。

  • salt_size (int) – 自动生成新盐时使用的可选字节数。默认为 16 字节,但可以是 0 到 1024 之间的任何值。

所以你可以设置你自己的预生成盐:

>>> from passlib.hash import pbkdf2_sha256
>>> pbkdf2_sha256.hash("password", rounds=200000, salt=b'spamhameggs')
'$pbkdf2-sha256$200000$c3BhbWhhbWVnZ3M$WL9OLVcb3f7HqHeNT./kCJeunydLCi4JykzEuAdewcI'

但是,请注意盐是返回字符串的一部分。该字符串不仅包含生成的哈希,还包含算法、使用的轮数使用的盐,由$ 分隔。盐是encoded to modified form of base64。您可以通过再次解码字符串c3BhbWhhbWVnZ3M 来验证这一点::

>>> from passlib.utils.binary import ab64_decode
>>> ab64_decode(b'c3BhbWhhbWVnZ3M')
b'spamhameggs'

有关pbkdf2_sha256 文档,请参阅Format & Algorithm 部分。

因此,当您将完整的字符串 pbkdf2_sha256 存储在数据库中时,验证字符串的所有内容都在值中,包括盐。最好将生成随机盐留给该库,因为它将使用安全的方法来生成一个。

您可能想阅读Passlib tutorial on password hashing,其中包括在将密码存储在数据库中时如何散列密码,以及如何再次验证密码(例如使用pdkdf2_sha256.verify(password_user_entered, hash_stored_in_database)),其中涵盖了这一点。

【讨论】:

    猜你喜欢
    • 2019-10-02
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2018-07-20
    • 2017-09-07
    • 2014-11-27
    相关资源
    最近更新 更多