hip*_*olt 4 python mysql salt pbkdf2 python-3.x
按照本教程,我只是在使用 MySQL 和 Python 进行开发时学习如何保护密码。
我的理解是用户密码存储在散列的数据库中,而盐并没有加密存储,因此我们可以获取散列的密码和盐,并使用盐重新散列输入的密码,然后比较两者。
但是,当使用 PBKDF2(通过passlib.hash.sha256_crypt()函数)时,我不能设置自己的盐,只能设置它的大小。那么如何使用相同的盐重新哈希密码,以便我可以比较两者?
该Passlib密码哈希界面要么允许您设置盐大小,或该salt值本身。从文档中pbkdf2_sha256:
salt( bytes ) 可选的盐字节。如果指定,长度必须在 0-1024 字节之间。如果未指定,将自动生成 16 字节的 salt(推荐使用)。
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'
Run Code Online (Sandbox Code Playgroud)
但是,请注意盐是返回字符串的一部分。字符串中包含不仅所得到的散列,而且所述算法,使用循环数和使用的盐,由分隔$。盐被编码为 base64 的修改形式。您可以通过c3BhbWhhbWVnZ3M再次解码字符串来验证这一点:
>>> from passlib.utils.binary import ab64_decode
>>> ab64_decode(b'c3BhbWhhbWVnZ3M')
b'spamhameggs'
Run Code Online (Sandbox Code Playgroud)
有关文档,请参阅格式和算法部分pbkdf2_sha256。
因此,当您将完整字符串存储pbkdf2_sha256在数据库中时,验证字符串的所有内容都在值中,包括盐。最好将生成随机盐留给该库,因为它将使用一种安全的方法来生成一个。
您可能需要阅读密码散列的Passlib 教程,其中涵盖了如何在数据库中存储时散列密码,以及如何再次验证它们(例如使用pdkdf2_sha256.verify(password_user_entered, hash_stored_in_database)),这恰好涵盖了这一点。