我使用mitsuhiko的pbkdf2实现进行密码哈希:
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
return map(ord, h.digest())
buf = []
for block in xrange(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block))
for i in xrange(iterations - 1):
u = _pseudorandom(''.join(map(chr, u)))
rv = starmap(xor, izip(rv, u))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
这个函数返回二进制摘要,然后将其编码为Base64并保存到数据库中。当用户登录时,此Base64字符串也会被设置为cookie。
此函数用于比较密码哈希值:
def comparePasswords(password1, password2):
if len(password1) != len(password2):
return False
diff = 0
for x, y in izip(password1, password2):
diff |= ord(x) ^ ord(y)
return diff == 0
我想知道在安全方面,比较二进制哈希和base64字符串是否有差别?例如,当用户登录时,我计算所提交的密码的二进制摘要,从数据库中解码base64字符串,然后将两个二进制哈希进行比较。但如果用户具有包含base64字符串的cookie,则直接将其与数据库中的字符串进行比较。
第二个问题是关于盐:
os.urandom返回二进制字符串,但在用于哈希生成之前,我还将其编码为base64。我不应该使用二进制形式的盐吗?