Jua*_*oto 6 python hash salt bcrypt
使用bcryptPython 2.7,我可以看到该示例使用bcrypt.hashpw散列密码进行存储并验证给定的密码是否与散列密码相匹配,如下所示:
import bcrypt
password = b"somepassword"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
Run Code Online (Sandbox Code Playgroud)
好的,到目前为止一切顺利.现在使用bcrypt对给定的密码进行哈希处理,因此它是一个哈希字节的字符串.
现在,这是令我困惑的部分:要检查明文密码是否与哈希密码匹配,使用相同的函数,使用哈希密码作为salt:
if bcrypt.hashpw(password, hashed) == hashed:
print("It Matches!")
else:
print("It Does not Match :(")
Run Code Online (Sandbox Code Playgroud)
两种bcrypt.hashpw调用的结果不应该不同,因为输入盐是不同的吗?
我能想到的唯一合理的答案是,在将前缀添加到哈希密码之前,盐被截断为固定长度.这样一来,使用散列的结果时,仅将所生成的盐是左(剥离后散列密码后),和散列与截短的盐密码的结果是相同的原件.但是,我没有任何证据支持这一点.
为什么这样做?
在表达式中,bcrypt.hashpw(password, hashed)只有前几个字符hashed用于salt,而不是整个字符串.
例如,在此示例中,输出是如何hashpw()从salt开始的:
salt1 = b"$2a$12$w40nlebw3XyoZ5Cqke14M."
print "salt1:", salt1
print "hash1:", bcrypt.hashpw(password, salt1)
Run Code Online (Sandbox Code Playgroud)
打印:
salt1: $2a$12$w40nlebw3XyoZ5Cqke14M.
hash1: $2a$12$w40nlebw3XyoZ5Cqke14M.d.7cdO2wJhr/K6ZSDjODIxLrPmYzY/a
Run Code Online (Sandbox Code Playgroud)
所以有一个惯例,盐只上升第一个时期或前29个字符.
该hashpw函数返回salted哈希(迭代多次,遵循bcyrpt规范),前面是使用的盐(并且以点作为分隔符).
In : salt = bcrypt.gensalt()
In : all(salt == bcrypt.hashpw(pw,salt)[:len(salt)] for pw in ('','12345','asdfgh'))
Out: True
Run Code Online (Sandbox Code Playgroud)
如果第二个参数to bcrypt.hashpw被识别为表单VALID_SALT.VALID_HASH,那么salt将自动设置为VALID_SALT,从而在相同的pw输入上生成与原始密码相同的salt-hash-pair .